Search in sources :

Example 21 with ContentVerifierProvider

use of org.bouncycastle.operator.ContentVerifierProvider in project xipki by xipki.

the class OcspServerImpl method checkSignature.

// method initStore
private Object checkSignature(byte[] request, RequestOption requestOption) throws OCSPException, CertificateParsingException, InvalidAlgorithmParameterException {
    OCSPRequest req;
    try {
        if (!requestOption.isValidateSignature()) {
            return OcspRequest.getInstance(request);
        }
        if (!OcspRequest.containsSignature(request)) {
            if (requestOption.isSignatureRequired()) {
                LOG.warn("signature in request required");
                return unsuccesfulOCSPRespMap.get(OcspResponseStatus.sigRequired);
            } else {
                return OcspRequest.getInstance(request);
            }
        }
        try {
            req = OCSPRequest.getInstance(request);
        } catch (IllegalArgumentException ex) {
            throw new EncodingException("could not parse OCSP request", ex);
        }
    } catch (EncodingException ex) {
        return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
    }
    OCSPReq ocspReq = new OCSPReq(req);
    X509CertificateHolder[] certs = ocspReq.getCerts();
    if (certs == null || certs.length < 1) {
        LOG.warn("no certificate found in request to verify the signature");
        return unsuccesfulOCSPRespMap.get(OcspResponseStatus.unauthorized);
    }
    ContentVerifierProvider cvp;
    try {
        cvp = securityFactory.getContentVerifierProvider(certs[0]);
    } catch (InvalidKeyException ex) {
        String message = ex.getMessage();
        LOG.warn("securityFactory.getContentVerifierProvider, InvalidKeyException: {}", message);
        return unsuccesfulOCSPRespMap.get(OcspResponseStatus.unauthorized);
    }
    boolean sigValid = ocspReq.isSignatureValid(cvp);
    if (!sigValid) {
        LOG.warn("request signature is invalid");
        return unsuccesfulOCSPRespMap.get(OcspResponseStatus.unauthorized);
    }
    // validate the certPath
    Date referenceTime = new Date();
    if (canBuildCertpath(certs, requestOption, referenceTime)) {
        try {
            return OcspRequest.getInstance(req);
        } catch (EncodingException ex) {
            return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
        }
    }
    LOG.warn("could not build certpath for the request's signer certificate");
    return unsuccesfulOCSPRespMap.get(OcspResponseStatus.unauthorized);
}
Also used : EncodingException(org.xipki.ocsp.server.impl.type.EncodingException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) OCSPReq(org.bouncycastle.cert.ocsp.OCSPReq) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) InvalidKeyException(java.security.InvalidKeyException) Date(java.util.Date) OCSPRequest(org.bouncycastle.asn1.ocsp.OCSPRequest) ContentVerifierProvider(org.bouncycastle.operator.ContentVerifierProvider)

Example 22 with ContentVerifierProvider

use of org.bouncycastle.operator.ContentVerifierProvider in project xipki by xipki.

the class OcspQa method checkOcsp.

public ValidationResult checkOcsp(OCSPResp response, IssuerHash issuerHash, List<BigInteger> serialNumbers, Map<BigInteger, byte[]> encodedCerts, OcspError expectedOcspError, Map<BigInteger, OcspCertStatus> expectedOcspStatuses, Map<BigInteger, Date> expectedRevTimes, OcspResponseOption responseOption, boolean noSigVerify) {
    ParamUtil.requireNonNull("response", response);
    ParamUtil.requireNonEmpty("serialNumbers", serialNumbers);
    ParamUtil.requireNonEmpty("expectedOcspStatuses", expectedOcspStatuses);
    ParamUtil.requireNonNull("responseOption", responseOption);
    List<ValidationIssue> resultIssues = new LinkedList<ValidationIssue>();
    int status = response.getStatus();
    // Response status
    ValidationIssue issue = new ValidationIssue("OCSP.STATUS", "response.status");
    resultIssues.add(issue);
    if (expectedOcspError != null) {
        if (status != expectedOcspError.getStatus()) {
            issue.setFailureMessage("is '" + status + "', but expected '" + expectedOcspError.getStatus() + "'");
        }
    } else {
        if (status != 0) {
            issue.setFailureMessage("is '" + status + "', but expected '0'");
        }
    }
    if (status != 0) {
        return new ValidationResult(resultIssues);
    }
    ValidationIssue encodingIssue = new ValidationIssue("OCSP.ENCODING", "response encoding");
    resultIssues.add(encodingIssue);
    BasicOCSPResp basicResp;
    try {
        basicResp = (BasicOCSPResp) response.getResponseObject();
    } catch (OCSPException ex) {
        encodingIssue.setFailureMessage(ex.getMessage());
        return new ValidationResult(resultIssues);
    }
    SingleResp[] singleResponses = basicResp.getResponses();
    issue = new ValidationIssue("OCSP.RESPONSES.NUM", "number of single responses");
    resultIssues.add(issue);
    if (singleResponses == null || singleResponses.length == 0) {
        issue.setFailureMessage("received no status from server");
        return new ValidationResult(resultIssues);
    }
    final int n = singleResponses.length;
    if (n != serialNumbers.size()) {
        issue.setFailureMessage("is '" + n + "', but expected '" + serialNumbers.size() + "'");
        return new ValidationResult(resultIssues);
    }
    boolean hasSignature = basicResp.getSignature() != null;
    // check the signature if available
    if (noSigVerify) {
        issue = new ValidationIssue("OCSP.SIG", (hasSignature ? "signature presence (Ignore)" : "signature presence"));
    } else {
        issue = new ValidationIssue("OCSP.SIG", "signature presence");
    }
    resultIssues.add(issue);
    if (!hasSignature) {
        issue.setFailureMessage("response is not signed");
    }
    if (hasSignature & !noSigVerify) {
        // signature algorithm
        issue = new ValidationIssue("OCSP.SIG.ALG", "signature algorithm");
        resultIssues.add(issue);
        String expectedSigalgo = responseOption.getSignatureAlgName();
        if (expectedSigalgo != null) {
            AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID();
            try {
                String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg);
                if (!AlgorithmUtil.equalsAlgoName(sigAlgName, expectedSigalgo)) {
                    issue.setFailureMessage("is '" + sigAlgName + "', but expected '" + expectedSigalgo + "'");
                }
            } catch (NoSuchAlgorithmException ex) {
                issue.setFailureMessage("could not extract the signature algorithm");
            }
        }
        // end if (expectedSigalgo != null)
        // signer certificate
        ValidationIssue sigSignerCertIssue = new ValidationIssue("OCSP.SIGNERCERT", "signer certificate");
        resultIssues.add(sigSignerCertIssue);
        // signature validation
        ValidationIssue sigValIssue = new ValidationIssue("OCSP.SIG.VALIDATION", "signature validation");
        resultIssues.add(sigValIssue);
        X509CertificateHolder respSigner = null;
        X509CertificateHolder[] responderCerts = basicResp.getCerts();
        if (responderCerts == null || responderCerts.length < 1) {
            sigSignerCertIssue.setFailureMessage("no responder certificate is contained in the response");
            sigValIssue.setFailureMessage("could not find certificate to validate signature");
        } else {
            ResponderID respId = basicResp.getResponderId().toASN1Primitive();
            X500Name respIdByName = respId.getName();
            byte[] respIdByKey = respId.getKeyHash();
            for (X509CertificateHolder cert : responderCerts) {
                if (respIdByName != null) {
                    if (cert.getSubject().equals(respIdByName)) {
                        respSigner = cert;
                    }
                } else {
                    byte[] spkiSha1 = HashAlgo.SHA1.hash(cert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes());
                    if (Arrays.equals(respIdByKey, spkiSha1)) {
                        respSigner = cert;
                    }
                }
                if (respSigner != null) {
                    break;
                }
            }
            if (respSigner == null) {
                sigSignerCertIssue.setFailureMessage("no responder certificate match the ResponderId");
                sigValIssue.setFailureMessage("could not find certificate matching the" + " ResponderId to validate signature");
            }
        }
        if (respSigner != null) {
            issue = new ValidationIssue("OCSP.SIGNERCERT.TRUST", "signer certificate validation");
            resultIssues.add(issue);
            for (int i = 0; i < singleResponses.length; i++) {
                SingleResp singleResp = singleResponses[i];
                if (!respSigner.isValidOn(singleResp.getThisUpdate())) {
                    issue.setFailureMessage(String.format("responder certificate is not valid on the thisUpdate[%d]: %s", i, singleResp.getThisUpdate()));
                }
            }
            // end for
            X509Certificate respIssuer = responseOption.getRespIssuer();
            if (!issue.isFailed() && respIssuer != null) {
                X509Certificate jceRespSigner;
                try {
                    jceRespSigner = X509Util.toX509Cert(respSigner.toASN1Structure());
                    if (X509Util.issues(respIssuer, jceRespSigner)) {
                        jceRespSigner.verify(respIssuer.getPublicKey());
                    } else {
                        issue.setFailureMessage("responder signer is not trusted");
                    }
                } catch (Exception ex) {
                    issue.setFailureMessage("responder signer is not trusted");
                }
            }
            try {
                PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo());
                ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(responderPubKey);
                boolean sigValid = basicResp.isSignatureValid(cvp);
                if (!sigValid) {
                    sigValIssue.setFailureMessage("signature is invalid");
                }
            } catch (Exception ex) {
                sigValIssue.setFailureMessage("could not validate signature");
            }
        }
    // end if
    }
    // end if (hasSignature)
    // nonce
    Extension nonceExtn = basicResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
    resultIssues.add(checkOccurrence("OCSP.NONCE", nonceExtn, responseOption.getNonceOccurrence()));
    boolean extendedRevoke = basicResp.getExtension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke) != null;
    for (int i = 0; i < singleResponses.length; i++) {
        SingleResp singleResp = singleResponses[i];
        BigInteger serialNumber = singleResp.getCertID().getSerialNumber();
        OcspCertStatus expectedStatus = expectedOcspStatuses.get(serialNumber);
        Date expectedRevTime = null;
        if (expectedRevTimes != null) {
            expectedRevTime = expectedRevTimes.get(serialNumber);
        }
        byte[] encodedCert = null;
        if (encodedCerts != null) {
            encodedCert = encodedCerts.get(serialNumber);
        }
        List<ValidationIssue> issues = checkSingleCert(i, singleResp, issuerHash, expectedStatus, encodedCert, expectedRevTime, extendedRevoke, responseOption.getNextUpdateOccurrence(), responseOption.getCerthashOccurrence(), responseOption.getCerthashAlgId());
        resultIssues.addAll(issues);
    }
    return new ValidationResult(resultIssues);
}
Also used : ResponderID(org.bouncycastle.asn1.ocsp.ResponderID) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) X500Name(org.bouncycastle.asn1.x500.X500Name) ValidationResult(org.xipki.common.qa.ValidationResult) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) OCSPException(org.bouncycastle.cert.ocsp.OCSPException) SingleResp(org.bouncycastle.cert.ocsp.SingleResp) ContentVerifierProvider(org.bouncycastle.operator.ContentVerifierProvider) PublicKey(java.security.PublicKey) ValidationIssue(org.xipki.common.qa.ValidationIssue) LinkedList(java.util.LinkedList) X509Certificate(java.security.cert.X509Certificate) OCSPException(org.bouncycastle.cert.ocsp.OCSPException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) Date(java.util.Date) Extension(org.bouncycastle.asn1.x509.Extension) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) BigInteger(java.math.BigInteger)

Example 23 with ContentVerifierProvider

use of org.bouncycastle.operator.ContentVerifierProvider in project xipki by xipki.

the class X509CaCmpResponderImpl method verifyPopo.

// method revokePendingCertificates
private boolean verifyPopo(CertificateRequestMessage certRequest, boolean allowRaPopo) {
    int popType = certRequest.getProofOfPossessionType();
    if (popType == CertificateRequestMessage.popRaVerified && allowRaPopo) {
        return true;
    }
    if (popType != CertificateRequestMessage.popSigningKey) {
        LOG.error("unsupported POP type: " + popType);
        return false;
    }
    // check the POP signature algorithm
    ProofOfPossession pop = certRequest.toASN1Structure().getPopo();
    POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject());
    AlgorithmIdentifier popoAlgId = popoSign.getAlgorithmIdentifier();
    AlgorithmValidator algoValidator = getCmpControl().getPopoAlgoValidator();
    if (!algoValidator.isAlgorithmPermitted(popoAlgId)) {
        String algoName;
        try {
            algoName = AlgorithmUtil.getSignatureAlgoName(popoAlgId);
        } catch (NoSuchAlgorithmException ex) {
            algoName = popoAlgId.getAlgorithm().getId();
        }
        LOG.error("POPO signature algorithm {} not permitted", algoName);
        return false;
    }
    try {
        PublicKey publicKey = securityFactory.generatePublicKey(certRequest.getCertTemplate().getPublicKey());
        ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(publicKey);
        return certRequest.isValidSigningKeyPOP(cvp);
    } catch (InvalidKeyException | IllegalStateException | CRMFException ex) {
        LogUtil.error(LOG, ex);
    }
    return false;
}
Also used : AlgorithmValidator(org.xipki.security.AlgorithmValidator) PublicKey(java.security.PublicKey) ProofOfPossession(org.bouncycastle.asn1.crmf.ProofOfPossession) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) CRMFException(org.bouncycastle.cert.crmf.CRMFException) POPOSigningKey(org.bouncycastle.asn1.crmf.POPOSigningKey) ContentVerifierProvider(org.bouncycastle.operator.ContentVerifierProvider)

Example 24 with ContentVerifierProvider

use of org.bouncycastle.operator.ContentVerifierProvider in project xipki by xipki.

the class SecurityFactoryImpl method verifyPopo.

@Override
public boolean verifyPopo(PKCS10CertificationRequest csr, AlgorithmValidator algoValidator) {
    if (algoValidator != null) {
        AlgorithmIdentifier algId = csr.getSignatureAlgorithm();
        if (!algoValidator.isAlgorithmPermitted(algId)) {
            String algoName;
            try {
                algoName = AlgorithmUtil.getSignatureAlgoName(algId);
            } catch (NoSuchAlgorithmException ex) {
                algoName = algId.getAlgorithm().getId();
            }
            LOG.error("POPO signature algorithm {} not permitted", algoName);
            return false;
        }
    }
    try {
        SubjectPublicKeyInfo pkInfo = csr.getSubjectPublicKeyInfo();
        PublicKey pk = KeyUtil.generatePublicKey(pkInfo);
        ContentVerifierProvider cvp = getContentVerifierProvider(pk);
        return csr.isSignatureValid(cvp);
    } catch (InvalidKeyException | PKCSException | NoSuchAlgorithmException | InvalidKeySpecException ex) {
        LogUtil.error(LOG, ex, "could not validate POPO of CSR");
        return false;
    }
}
Also used : PublicKey(java.security.PublicKey) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) InvalidKeyException(java.security.InvalidKeyException) SubjectPublicKeyInfo(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo) PKCSException(org.bouncycastle.pkcs.PKCSException) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) ContentVerifierProvider(org.bouncycastle.operator.ContentVerifierProvider)

Example 25 with ContentVerifierProvider

use of org.bouncycastle.operator.ContentVerifierProvider in project xipki by xipki.

the class CaEmulator method verifyPopo.

// method getCrl
private boolean verifyPopo(CertificationRequest csr) {
    Args.notNull(csr, "csr");
    try {
        PKCS10CertificationRequest p10Req = new PKCS10CertificationRequest(csr);
        SubjectPublicKeyInfo pkInfo = p10Req.getSubjectPublicKeyInfo();
        PublicKey pk = generatePublicKey(pkInfo);
        ContentVerifierProvider cvp = getContentVerifierProvider(pk);
        return p10Req.isSignatureValid(cvp);
    } catch (InvalidKeyException | PKCSException | InvalidKeySpecException ex) {
        LOG.error("could not validate POPO of CSR", ex);
        return false;
    }
}
Also used : PKCS10CertificationRequest(org.bouncycastle.pkcs.PKCS10CertificationRequest) RSAPublicKey(java.security.interfaces.RSAPublicKey) DSAPublicKey(java.security.interfaces.DSAPublicKey) ECPublicKey(java.security.interfaces.ECPublicKey) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) PKCSException(org.bouncycastle.pkcs.PKCSException) ContentVerifierProvider(org.bouncycastle.operator.ContentVerifierProvider)

Aggregations

ContentVerifierProvider (org.bouncycastle.operator.ContentVerifierProvider)31 AlgorithmIdentifier (org.bouncycastle.asn1.x509.AlgorithmIdentifier)12 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)11 PublicKey (java.security.PublicKey)10 X500Name (org.bouncycastle.asn1.x500.X500Name)10 JcaContentVerifierProviderBuilder (org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder)10 OperatorCreationException (org.bouncycastle.operator.OperatorCreationException)9 X509Certificate (java.security.cert.X509Certificate)8 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)7 BigInteger (java.math.BigInteger)6 InvalidKeyException (java.security.InvalidKeyException)6 IOException (java.io.IOException)5 Date (java.util.Date)5 Extension (org.bouncycastle.asn1.x509.Extension)5 ProtectedPKIMessage (org.bouncycastle.cert.cmp.ProtectedPKIMessage)4 BasicOCSPResp (org.bouncycastle.cert.ocsp.BasicOCSPResp)4 OCSPReq (org.bouncycastle.cert.ocsp.OCSPReq)4 GeneralSecurityException (java.security.GeneralSecurityException)3 KeyPair (java.security.KeyPair)3 Signature (java.security.Signature)3