Search in sources :

Example 26 with Time

use of org.spongycastle.asn1.x509.Time in project xipki by xipki.

the class EnrollCertAction method execute0.

@Override
protected Object execute0() throws Exception {
    if (caName != null) {
        caName = caName.toLowerCase();
    }
    CertTemplateBuilder certTemplateBuilder = new CertTemplateBuilder();
    ConcurrentContentSigner signer = getSigner(new SignatureAlgoControl(rsaMgf1, dsaPlain, gm));
    X509CertificateHolder ssCert = signer.getBcCertificate();
    X500Name x500Subject = new X500Name(subject);
    certTemplateBuilder.setSubject(x500Subject);
    certTemplateBuilder.setPublicKey(ssCert.getSubjectPublicKeyInfo());
    if (StringUtil.isNotBlank(notBeforeS) || StringUtil.isNotBlank(notAfterS)) {
        Time notBefore = StringUtil.isNotBlank(notBeforeS) ? new Time(DateUtil.parseUtcTimeyyyyMMddhhmmss(notBeforeS)) : null;
        Time notAfter = StringUtil.isNotBlank(notAfterS) ? new Time(DateUtil.parseUtcTimeyyyyMMddhhmmss(notAfterS)) : null;
        OptionalValidity validity = new OptionalValidity(notBefore, notAfter);
        certTemplateBuilder.setValidity(validity);
    }
    if (needExtensionTypes == null) {
        needExtensionTypes = new LinkedList<>();
    }
    // SubjectAltNames
    List<Extension> extensions = new LinkedList<>();
    if (isNotEmpty(subjectAltNames)) {
        extensions.add(X509Util.createExtnSubjectAltName(subjectAltNames, false));
        needExtensionTypes.add(Extension.subjectAlternativeName.getId());
    }
    // SubjectInfoAccess
    if (isNotEmpty(subjectInfoAccesses)) {
        extensions.add(X509Util.createExtnSubjectInfoAccess(subjectInfoAccesses, false));
        needExtensionTypes.add(Extension.subjectInfoAccess.getId());
    }
    // Keyusage
    if (isNotEmpty(keyusages)) {
        Set<KeyUsage> usages = new HashSet<>();
        for (String usage : keyusages) {
            usages.add(KeyUsage.getKeyUsage(usage));
        }
        org.bouncycastle.asn1.x509.KeyUsage extValue = X509Util.createKeyUsage(usages);
        ASN1ObjectIdentifier extType = Extension.keyUsage;
        extensions.add(new Extension(extType, false, extValue.getEncoded()));
        needExtensionTypes.add(extType.getId());
    }
    // ExtendedKeyusage
    if (isNotEmpty(extkeyusages)) {
        ExtendedKeyUsage extValue = X509Util.createExtendedUsage(textToAsn1ObjectIdentifers(extkeyusages));
        ASN1ObjectIdentifier extType = Extension.extendedKeyUsage;
        extensions.add(new Extension(extType, false, extValue.getEncoded()));
        needExtensionTypes.add(extType.getId());
    }
    // QcEuLimitValue
    if (isNotEmpty(qcEuLimits)) {
        ASN1EncodableVector vec = new ASN1EncodableVector();
        for (String m : qcEuLimits) {
            StringTokenizer st = new StringTokenizer(m, ":");
            try {
                String currencyS = st.nextToken();
                String amountS = st.nextToken();
                String exponentS = st.nextToken();
                Iso4217CurrencyCode currency;
                try {
                    int intValue = Integer.parseInt(currencyS);
                    currency = new Iso4217CurrencyCode(intValue);
                } catch (NumberFormatException ex) {
                    currency = new Iso4217CurrencyCode(currencyS);
                }
                int amount = Integer.parseInt(amountS);
                int exponent = Integer.parseInt(exponentS);
                MonetaryValue monterayValue = new MonetaryValue(currency, amount, exponent);
                QCStatement statment = new QCStatement(ObjectIdentifiers.id_etsi_qcs_QcLimitValue, monterayValue);
                vec.add(statment);
            } catch (Exception ex) {
                throw new Exception("invalid qc-eu-limit '" + m + "'");
            }
        }
        ASN1ObjectIdentifier extType = Extension.qCStatements;
        ASN1Sequence extValue = new DERSequence(vec);
        extensions.add(new Extension(extType, false, extValue.getEncoded()));
        needExtensionTypes.add(extType.getId());
    }
    // biometricInfo
    if (biometricType != null && biometricHashAlgo != null && biometricFile != null) {
        TypeOfBiometricData objBiometricType = StringUtil.isNumber(biometricType) ? new TypeOfBiometricData(Integer.parseInt(biometricType)) : new TypeOfBiometricData(new ASN1ObjectIdentifier(biometricType));
        ASN1ObjectIdentifier objBiometricHashAlgo = AlgorithmUtil.getHashAlg(biometricHashAlgo);
        byte[] biometricBytes = IoUtil.read(biometricFile);
        MessageDigest md = MessageDigest.getInstance(objBiometricHashAlgo.getId());
        md.reset();
        byte[] biometricDataHash = md.digest(biometricBytes);
        DERIA5String sourceDataUri = null;
        if (biometricUri != null) {
            sourceDataUri = new DERIA5String(biometricUri);
        }
        BiometricData biometricData = new BiometricData(objBiometricType, new AlgorithmIdentifier(objBiometricHashAlgo), new DEROctetString(biometricDataHash), sourceDataUri);
        ASN1EncodableVector vec = new ASN1EncodableVector();
        vec.add(biometricData);
        ASN1ObjectIdentifier extType = Extension.biometricInfo;
        ASN1Sequence extValue = new DERSequence(vec);
        extensions.add(new Extension(extType, false, extValue.getEncoded()));
        needExtensionTypes.add(extType.getId());
    } else if (biometricType == null && biometricHashAlgo == null && biometricFile == null) {
    // Do nothing
    } else {
        throw new Exception("either all of biometric triples (type, hash algo, file)" + " must be set or none of them should be set");
    }
    if (isNotEmpty(needExtensionTypes) || isNotEmpty(wantExtensionTypes)) {
        ExtensionExistence ee = new ExtensionExistence(textToAsn1ObjectIdentifers(needExtensionTypes), textToAsn1ObjectIdentifers(wantExtensionTypes));
        extensions.add(new Extension(ObjectIdentifiers.id_xipki_ext_cmpRequestExtensions, false, ee.toASN1Primitive().getEncoded()));
    }
    if (isNotEmpty(extensions)) {
        Extensions asn1Extensions = new Extensions(extensions.toArray(new Extension[0]));
        certTemplateBuilder.setExtensions(asn1Extensions);
    }
    CertRequest certReq = new CertRequest(1, certTemplateBuilder.build(), null);
    ProofOfPossessionSigningKeyBuilder popoBuilder = new ProofOfPossessionSigningKeyBuilder(certReq);
    ConcurrentBagEntrySigner signer0 = signer.borrowSigner();
    POPOSigningKey popoSk;
    try {
        popoSk = popoBuilder.build(signer0.value());
    } finally {
        signer.requiteSigner(signer0);
    }
    ProofOfPossession popo = new ProofOfPossession(popoSk);
    EnrollCertRequestEntry reqEntry = new EnrollCertRequestEntry("id-1", profile, certReq, popo);
    EnrollCertRequest request = new EnrollCertRequest(EnrollCertRequest.Type.CERT_REQ);
    request.addRequestEntry(reqEntry);
    RequestResponseDebug debug = getRequestResponseDebug();
    EnrollCertResult result;
    try {
        result = caClient.requestCerts(caName, request, debug);
    } finally {
        saveRequestResponse(debug);
    }
    X509Certificate cert = null;
    if (result != null) {
        String id = result.getAllIds().iterator().next();
        CertOrError certOrError = result.getCertOrError(id);
        cert = (X509Certificate) certOrError.getCertificate();
    }
    if (cert == null) {
        throw new CmdFailure("no certificate received from the server");
    }
    File certFile = new File(outputFile);
    saveVerbose("saved certificate to file", certFile, cert.getEncoded());
    return null;
}
Also used : TypeOfBiometricData(org.bouncycastle.asn1.x509.qualified.TypeOfBiometricData) BiometricData(org.bouncycastle.asn1.x509.qualified.BiometricData) ExtendedKeyUsage(org.bouncycastle.asn1.x509.ExtendedKeyUsage) KeyUsage(org.xipki.security.KeyUsage) X500Name(org.bouncycastle.asn1.x500.X500Name) DEROctetString(org.bouncycastle.asn1.DEROctetString) DERIA5String(org.bouncycastle.asn1.DERIA5String) DEROctetString(org.bouncycastle.asn1.DEROctetString) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) DERSequence(org.bouncycastle.asn1.DERSequence) EnrollCertRequestEntry(org.xipki.ca.client.api.dto.EnrollCertRequestEntry) ASN1EncodableVector(org.bouncycastle.asn1.ASN1EncodableVector) MessageDigest(java.security.MessageDigest) ExtendedKeyUsage(org.bouncycastle.asn1.x509.ExtendedKeyUsage) TypeOfBiometricData(org.bouncycastle.asn1.x509.qualified.TypeOfBiometricData) HashSet(java.util.HashSet) RequestResponseDebug(org.xipki.common.RequestResponseDebug) ProofOfPossession(org.bouncycastle.asn1.crmf.ProofOfPossession) LinkedList(java.util.LinkedList) X509Certificate(java.security.cert.X509Certificate) OptionalValidity(org.bouncycastle.asn1.crmf.OptionalValidity) ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) ProofOfPossessionSigningKeyBuilder(org.bouncycastle.cert.crmf.ProofOfPossessionSigningKeyBuilder) File(java.io.File) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) QCStatement(org.bouncycastle.asn1.x509.qualified.QCStatement) EnrollCertRequest(org.xipki.ca.client.api.dto.EnrollCertRequest) Time(org.bouncycastle.asn1.x509.Time) Extensions(org.bouncycastle.asn1.x509.Extensions) Iso4217CurrencyCode(org.bouncycastle.asn1.x509.qualified.Iso4217CurrencyCode) DERIA5String(org.bouncycastle.asn1.DERIA5String) CertTemplateBuilder(org.bouncycastle.asn1.crmf.CertTemplateBuilder) CmdFailure(org.xipki.console.karaf.CmdFailure) EnrollCertResult(org.xipki.ca.client.api.EnrollCertResult) POPOSigningKey(org.bouncycastle.asn1.crmf.POPOSigningKey) MonetaryValue(org.bouncycastle.asn1.x509.qualified.MonetaryValue) ConcurrentBagEntrySigner(org.xipki.security.ConcurrentBagEntrySigner) CertOrError(org.xipki.ca.client.api.CertOrError) ObjectCreationException(org.xipki.common.ObjectCreationException) InvalidOidOrNameException(org.xipki.security.exception.InvalidOidOrNameException) Extension(org.bouncycastle.asn1.x509.Extension) StringTokenizer(java.util.StringTokenizer) ConcurrentContentSigner(org.xipki.security.ConcurrentContentSigner) ExtensionExistence(org.xipki.security.ExtensionExistence) EnrollCertRequest(org.xipki.ca.client.api.dto.EnrollCertRequest) CertRequest(org.bouncycastle.asn1.crmf.CertRequest) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) SignatureAlgoControl(org.xipki.security.SignatureAlgoControl)

Example 27 with Time

use of org.spongycastle.asn1.x509.Time in project xipki by xipki.

the class X509CertprofileQa method checkCert.

// constructor
public ValidationResult checkCert(byte[] certBytes, X509IssuerInfo issuerInfo, X500Name requestedSubject, SubjectPublicKeyInfo requestedPublicKey, Extensions requestedExtensions) {
    ParamUtil.requireNonNull("certBytes", certBytes);
    ParamUtil.requireNonNull("issuerInfo", issuerInfo);
    ParamUtil.requireNonNull("requestedSubject", requestedSubject);
    ParamUtil.requireNonNull("requestedPublicKey", requestedPublicKey);
    List<ValidationIssue> resultIssues = new LinkedList<ValidationIssue>();
    Certificate bcCert;
    TBSCertificate tbsCert;
    X509Certificate cert;
    ValidationIssue issue;
    // certificate size
    issue = new ValidationIssue("X509.SIZE", "certificate size");
    resultIssues.add(issue);
    Integer maxSize = certProfile.getMaxSize();
    if (maxSize != 0) {
        int size = certBytes.length;
        if (size > maxSize) {
            issue.setFailureMessage(String.format("certificate exceeds the maximal allowed size: %d > %d", size, maxSize));
        }
    }
    // certificate encoding
    issue = new ValidationIssue("X509.ENCODING", "certificate encoding");
    resultIssues.add(issue);
    try {
        bcCert = Certificate.getInstance(certBytes);
        tbsCert = bcCert.getTBSCertificate();
        cert = X509Util.parseCert(certBytes);
    } catch (CertificateException ex) {
        issue.setFailureMessage("certificate is not corrected encoded");
        return new ValidationResult(resultIssues);
    }
    // syntax version
    issue = new ValidationIssue("X509.VERSION", "certificate version");
    resultIssues.add(issue);
    int versionNumber = tbsCert.getVersionNumber();
    X509CertVersion expVersion = certProfile.getVersion();
    if (versionNumber != expVersion.getVersionNumber()) {
        issue.setFailureMessage("is '" + versionNumber + "' but expected '" + expVersion.getVersionNumber() + "'");
    }
    // serialNumber
    issue = new ValidationIssue("X509.serialNumber", "certificate serial number");
    resultIssues.add(issue);
    BigInteger serialNumber = tbsCert.getSerialNumber().getValue();
    if (serialNumber.signum() != 1) {
        issue.setFailureMessage("not positive");
    } else {
        if (serialNumber.bitLength() >= 160) {
            issue.setFailureMessage("serial number has more than 20 octets");
        }
    }
    // signatureAlgorithm
    List<String> signatureAlgorithms = certProfile.getSignatureAlgorithms();
    if (CollectionUtil.isNonEmpty(signatureAlgorithms)) {
        issue = new ValidationIssue("X509.SIGALG", "signature algorithm");
        resultIssues.add(issue);
        AlgorithmIdentifier sigAlgId = bcCert.getSignatureAlgorithm();
        AlgorithmIdentifier tbsSigAlgId = tbsCert.getSignature();
        if (!tbsSigAlgId.equals(sigAlgId)) {
            issue.setFailureMessage("Certificate.tbsCertificate.signature != Certificate.signatureAlgorithm");
        }
        try {
            String sigAlgo = AlgorithmUtil.getSignatureAlgoName(sigAlgId);
            if (!issue.isFailed()) {
                if (!signatureAlgorithms.contains(sigAlgo)) {
                    issue.setFailureMessage("signatureAlgorithm '" + sigAlgo + "' is not allowed");
                }
            }
            // check parameters
            if (!issue.isFailed()) {
                AlgorithmIdentifier expSigAlgId = AlgorithmUtil.getSigAlgId(sigAlgo);
                if (!expSigAlgId.equals(sigAlgId)) {
                    issue.setFailureMessage("invalid parameters");
                }
            }
        } catch (NoSuchAlgorithmException ex) {
            issue.setFailureMessage("unsupported signature algorithm " + sigAlgId.getAlgorithm().getId());
        }
    }
    // notBefore encoding
    issue = new ValidationIssue("X509.NOTBEFORE.ENCODING", "notBefore encoding");
    checkTime(tbsCert.getStartDate(), issue);
    // notAfter encoding
    issue = new ValidationIssue("X509.NOTAFTER.ENCODING", "notAfter encoding");
    checkTime(tbsCert.getStartDate(), issue);
    // notBefore
    if (certProfile.isNotBeforeMidnight()) {
        issue = new ValidationIssue("X509.NOTBEFORE", "notBefore midnight");
        resultIssues.add(issue);
        Calendar cal = Calendar.getInstance(UTC);
        cal.setTime(cert.getNotBefore());
        int hourOfDay = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);
        int second = cal.get(Calendar.SECOND);
        if (hourOfDay != 0 || minute != 0 || second != 0) {
            issue.setFailureMessage(" '" + cert.getNotBefore() + "' is not midnight time (UTC)");
        }
    }
    // validity
    issue = new ValidationIssue("X509.VALIDITY", "cert validity");
    resultIssues.add(issue);
    if (cert.getNotAfter().before(cert.getNotBefore())) {
        issue.setFailureMessage("notAfter must not be before notBefore");
    } else if (cert.getNotBefore().before(issuerInfo.getCaNotBefore())) {
        issue.setFailureMessage("notBefore must not be before CA's notBefore");
    } else {
        CertValidity validity = certProfile.getValidity();
        Date expectedNotAfter = validity.add(cert.getNotBefore());
        if (expectedNotAfter.getTime() > MAX_CERT_TIME_MS) {
            expectedNotAfter = new Date(MAX_CERT_TIME_MS);
        }
        if (issuerInfo.isCutoffNotAfter() && expectedNotAfter.after(issuerInfo.getCaNotAfter())) {
            expectedNotAfter = issuerInfo.getCaNotAfter();
        }
        if (Math.abs(expectedNotAfter.getTime() - cert.getNotAfter().getTime()) > 60 * SECOND) {
            issue.setFailureMessage("cert validity is not within " + validity.toString());
        }
    }
    // subjectPublicKeyInfo
    resultIssues.addAll(publicKeyChecker.checkPublicKey(bcCert.getSubjectPublicKeyInfo(), requestedPublicKey));
    // Signature
    issue = new ValidationIssue("X509.SIG", "whether certificate is signed by CA");
    resultIssues.add(issue);
    try {
        cert.verify(issuerInfo.getCert().getPublicKey(), "BC");
    } catch (Exception ex) {
        issue.setFailureMessage("invalid signature");
    }
    // issuer
    issue = new ValidationIssue("X509.ISSUER", "certificate issuer");
    resultIssues.add(issue);
    if (!cert.getIssuerX500Principal().equals(issuerInfo.getCert().getSubjectX500Principal())) {
        issue.setFailureMessage("issue in certificate does not equal the subject of CA certificate");
    }
    // subject
    resultIssues.addAll(subjectChecker.checkSubject(bcCert.getSubject(), requestedSubject));
    // issuerUniqueID
    issue = new ValidationIssue("X509.IssuerUniqueID", "issuerUniqueID");
    resultIssues.add(issue);
    if (tbsCert.getIssuerUniqueId() != null) {
        issue.setFailureMessage("is present but not permitted");
    }
    // subjectUniqueID
    issue = new ValidationIssue("X509.SubjectUniqueID", "subjectUniqueID");
    resultIssues.add(issue);
    if (tbsCert.getSubjectUniqueId() != null) {
        issue.setFailureMessage("is present but not permitted");
    }
    // extensions
    issue = new ValidationIssue("X509.GrantedSubject", "grantedSubject");
    resultIssues.add(issue);
    resultIssues.addAll(extensionsChecker.checkExtensions(bcCert, issuerInfo, requestedExtensions, requestedSubject));
    return new ValidationResult(resultIssues);
}
Also used : CertValidity(org.xipki.ca.api.profile.CertValidity) Calendar(java.util.Calendar) CertificateException(java.security.cert.CertificateException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ValidationResult(org.xipki.common.qa.ValidationResult) ValidationIssue(org.xipki.common.qa.ValidationIssue) LinkedList(java.util.LinkedList) X509Certificate(java.security.cert.X509Certificate) Date(java.util.Date) CertprofileException(org.xipki.ca.api.profile.CertprofileException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) IOException(java.io.IOException) CertificateException(java.security.cert.CertificateException) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) BigInteger(java.math.BigInteger) X509CertVersion(org.xipki.ca.api.profile.x509.X509CertVersion) BigInteger(java.math.BigInteger) TBSCertificate(org.bouncycastle.asn1.x509.TBSCertificate) X509Certificate(java.security.cert.X509Certificate) Certificate(org.bouncycastle.asn1.x509.Certificate) TBSCertificate(org.bouncycastle.asn1.x509.TBSCertificate)

Example 28 with Time

use of org.spongycastle.asn1.x509.Time in project candlepin by candlepin.

the class X509CRLStreamWriter method writeToEmptyCrl.

protected void writeToEmptyCrl(OutputStream out) throws IOException {
    ASN1InputStream asn1in = null;
    try {
        asn1in = new ASN1InputStream(crlIn);
        ASN1Sequence certListSeq = (ASN1Sequence) asn1in.readObject();
        CertificateList certList = CertificateList.getInstance(certListSeq);
        X509CRLHolder oldCrl = new X509CRLHolder(certList);
        X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(oldCrl.getIssuer(), new Date());
        crlBuilder.addCRL(oldCrl);
        Date now = new Date();
        Date oldNextUpdate = certList.getNextUpdate().getDate();
        Date oldThisUpdate = certList.getThisUpdate().getDate();
        Date nextUpdate = new Date(now.getTime() + (oldNextUpdate.getTime() - oldThisUpdate.getTime()));
        crlBuilder.setNextUpdate(nextUpdate);
        for (Object o : oldCrl.getExtensionOIDs()) {
            ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) o;
            Extension ext = oldCrl.getExtension(oid);
            if (oid.equals(Extension.cRLNumber)) {
                ASN1OctetString octet = ext.getExtnValue();
                ASN1Integer currentNumber = (ASN1Integer) new ASN1InputStream(octet.getOctets()).readObject();
                ASN1Integer nextNumber = new ASN1Integer(currentNumber.getValue().add(BigInteger.ONE));
                crlBuilder.addExtension(oid, ext.isCritical(), nextNumber);
            } else if (oid.equals(Extension.authorityKeyIdentifier)) {
                crlBuilder.addExtension(oid, ext.isCritical(), ext.getParsedValue());
            }
        }
        for (DERSequence entry : newEntries) {
            // XXX: This is all a bit messy considering the user already passed in the serial, date
            // and reason.
            BigInteger serial = ((ASN1Integer) entry.getObjectAt(0)).getValue();
            Date revokeDate = ((Time) entry.getObjectAt(1)).getDate();
            int reason = CRLReason.unspecified;
            if (entry.size() == 3) {
                Extensions extensions = (Extensions) entry.getObjectAt(2);
                Extension reasonExt = extensions.getExtension(Extension.reasonCode);
                if (reasonExt != null) {
                    reason = ((ASN1Enumerated) reasonExt.getParsedValue()).getValue().intValue();
                }
            }
            crlBuilder.addCRLEntry(serial, revokeDate, reason);
        }
        if (signingAlg == null) {
            signingAlg = oldCrl.toASN1Structure().getSignatureAlgorithm();
        }
        ContentSigner s;
        try {
            s = createContentSigner(signingAlg, key);
            X509CRLHolder newCrl = crlBuilder.build(s);
            out.write(newCrl.getEncoded());
        } catch (OperatorCreationException e) {
            throw new IOException("Could not sign CRL", e);
        }
    } finally {
        IOUtils.closeQuietly(asn1in);
    }
}
Also used : ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) ASN1InputStream(org.bouncycastle.asn1.ASN1InputStream) CertificateList(org.bouncycastle.asn1.x509.CertificateList) ContentSigner(org.bouncycastle.operator.ContentSigner) DERGeneralizedTime(org.bouncycastle.asn1.DERGeneralizedTime) ASN1GeneralizedTime(org.bouncycastle.asn1.ASN1GeneralizedTime) DERUTCTime(org.bouncycastle.asn1.DERUTCTime) Time(org.bouncycastle.asn1.x509.Time) ASN1UTCTime(org.bouncycastle.asn1.ASN1UTCTime) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) IOException(java.io.IOException) Extensions(org.bouncycastle.asn1.x509.Extensions) Date(java.util.Date) Extension(org.bouncycastle.asn1.x509.Extension) ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) DERSequence(org.bouncycastle.asn1.DERSequence) ASN1Enumerated(org.bouncycastle.asn1.ASN1Enumerated) X509CRLHolder(org.bouncycastle.cert.X509CRLHolder) BigInteger(java.math.BigInteger) X509v2CRLBuilder(org.bouncycastle.cert.X509v2CRLBuilder) ASN1Object(org.bouncycastle.asn1.ASN1Object) ASN1TaggedObject(org.bouncycastle.asn1.ASN1TaggedObject) DERTaggedObject(org.bouncycastle.asn1.DERTaggedObject) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Example 29 with Time

use of org.spongycastle.asn1.x509.Time in project netty by netty.

the class OcspRequestBuilder method build.

/**
 * ATTENTION: The returned {@link OCSPReq} is not re-usable/cacheable! It contains a one-time nonce
 * and CA's will (should) reject subsequent requests that have the same nonce value.
 */
public OCSPReq build() throws OCSPException, IOException, CertificateEncodingException {
    SecureRandom generator = checkNotNull(this.generator, "generator");
    DigestCalculator calculator = checkNotNull(this.calculator, "calculator");
    X509Certificate certificate = checkNotNull(this.certificate, "certificate");
    X509Certificate issuer = checkNotNull(this.issuer, "issuer");
    BigInteger serial = certificate.getSerialNumber();
    CertificateID certId = new CertificateID(calculator, new X509CertificateHolder(issuer.getEncoded()), serial);
    OCSPReqBuilder builder = new OCSPReqBuilder();
    builder.addRequest(certId);
    byte[] nonce = new byte[8];
    generator.nextBytes(nonce);
    Extension[] extensions = new Extension[] { new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, new DEROctetString(nonce)) };
    builder.setRequestExtensions(new Extensions(extensions));
    return builder.build();
}
Also used : Extension(org.bouncycastle.asn1.x509.Extension) CertificateID(org.bouncycastle.cert.ocsp.CertificateID) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) DigestCalculator(org.bouncycastle.operator.DigestCalculator) SecureRandom(java.security.SecureRandom) BigInteger(java.math.BigInteger) Extensions(org.bouncycastle.asn1.x509.Extensions) OCSPReqBuilder(org.bouncycastle.cert.ocsp.OCSPReqBuilder) X509Certificate(java.security.cert.X509Certificate) DEROctetString(org.bouncycastle.asn1.DEROctetString)

Example 30 with Time

use of org.spongycastle.asn1.x509.Time in project keycloak by keycloak.

the class OCSPUtils method verifyResponse.

private static void verifyResponse(BasicOCSPResp basicOcspResponse, X509Certificate issuerCertificate, X509Certificate responderCertificate, byte[] requestNonce, Date date) throws NoSuchProviderException, NoSuchAlgorithmException, CertificateNotYetValidException, CertificateExpiredException, CertPathValidatorException {
    List<X509CertificateHolder> certs = new ArrayList<>(Arrays.asList(basicOcspResponse.getCerts()));
    X509Certificate signingCert = null;
    try {
        certs.add(new JcaX509CertificateHolder(issuerCertificate));
        if (responderCertificate != null) {
            certs.add(new JcaX509CertificateHolder(responderCertificate));
        }
    } catch (CertificateEncodingException e) {
        e.printStackTrace();
    }
    if (certs.size() > 0) {
        X500Name responderName = basicOcspResponse.getResponderId().toASN1Primitive().getName();
        byte[] responderKey = basicOcspResponse.getResponderId().toASN1Primitive().getKeyHash();
        if (responderName != null) {
            logger.log(Level.INFO, "Responder Name: {0}", responderName.toString());
            for (X509CertificateHolder certHolder : certs) {
                try {
                    X509Certificate tempCert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);
                    X500Name respName = new X500Name(tempCert.getSubjectX500Principal().getName());
                    if (responderName.equals(respName)) {
                        signingCert = tempCert;
                        logger.log(Level.INFO, "Found a certificate whose principal \"{0}\" matches the responder name \"{1}\"", new Object[] { tempCert.getSubjectDN().getName(), responderName.toString() });
                        break;
                    }
                } catch (CertificateException e) {
                    logger.log(Level.FINE, e.getMessage());
                }
            }
        } else if (responderKey != null) {
            SubjectKeyIdentifier responderSubjectKey = new SubjectKeyIdentifier(responderKey);
            logger.log(Level.INFO, "Responder Key: {0}", Arrays.toString(responderKey));
            for (X509CertificateHolder certHolder : certs) {
                try {
                    X509Certificate tempCert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);
                    SubjectKeyIdentifier subjectKeyIdentifier = null;
                    if (certHolder.getExtensions() != null) {
                        subjectKeyIdentifier = SubjectKeyIdentifier.fromExtensions(certHolder.getExtensions());
                    }
                    if (subjectKeyIdentifier != null) {
                        logger.log(Level.INFO, "Certificate: {0}\nSubject Key Id: {1}", new Object[] { tempCert.getSubjectDN().getName(), Arrays.toString(subjectKeyIdentifier.getKeyIdentifier()) });
                    }
                    if (subjectKeyIdentifier != null && responderSubjectKey.equals(subjectKeyIdentifier)) {
                        signingCert = tempCert;
                        logger.log(Level.INFO, "Found a signer certificate \"{0}\" with the subject key extension value matching the responder key", signingCert.getSubjectDN().getName());
                        break;
                    }
                    subjectKeyIdentifier = new JcaX509ExtensionUtils().createSubjectKeyIdentifier(tempCert.getPublicKey());
                    if (responderSubjectKey.equals(subjectKeyIdentifier)) {
                        signingCert = tempCert;
                        logger.log(Level.INFO, "Found a certificate \"{0}\" with the subject key matching the OCSP responder key", signingCert.getSubjectDN().getName());
                        break;
                    }
                } catch (CertificateException e) {
                    logger.log(Level.FINE, e.getMessage());
                }
            }
        }
    }
    if (signingCert != null) {
        if (signingCert.equals(issuerCertificate)) {
            logger.log(Level.INFO, "OCSP response is signed by the target''s Issuing CA");
        } else if (responderCertificate != null && signingCert.equals(responderCertificate)) {
            // https://www.ietf.org/rfc/rfc2560.txt
            // 2.6  OCSP Signature Authority Delegation
            // - The responder certificate is issued to the responder by CA
            logger.log(Level.INFO, "OCSP response is signed by an authorized responder certificate");
        } else {
            // question."
            if (!signingCert.getIssuerX500Principal().equals(issuerCertificate.getSubjectX500Principal())) {
                logger.log(Level.INFO, "Signer certificate''s Issuer: {0}\nIssuer certificate''s Subject: {1}", new Object[] { signingCert.getIssuerX500Principal().getName(), issuerCertificate.getSubjectX500Principal().getName() });
                throw new CertPathValidatorException("Responder\'s certificate is not authorized to sign OCSP responses");
            }
            try {
                List<String> purposes = signingCert.getExtendedKeyUsage();
                if (purposes == null || !purposes.contains(KeyPurposeId.id_kp_OCSPSigning.getId())) {
                    logger.log(Level.INFO, "OCSPSigning extended usage is not set");
                    throw new CertPathValidatorException("Responder\'s certificate not valid for signing OCSP responses");
                }
            } catch (CertificateParsingException e) {
                logger.log(Level.FINE, "Failed to get certificate''s extended key usage extension\n{0}", e.getMessage());
            }
            if (date == null) {
                signingCert.checkValidity();
            } else {
                signingCert.checkValidity(date);
            }
            try {
                Extension noOCSPCheck = new JcaX509CertificateHolder(signingCert).getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck);
                // TODO If the extension is present, the OCSP client can trust the
                // responder's certificate for the lifetime of the certificate.
                logger.log(Level.INFO, "OCSP no-check extension is {0} present", noOCSPCheck == null ? "not" : "");
            } catch (CertificateEncodingException e) {
                logger.log(Level.FINE, "Certificate encoding exception: {0}", e.getMessage());
            }
            try {
                signingCert.verify(issuerCertificate.getPublicKey());
                logger.log(Level.INFO, "OCSP response is signed by an Authorized Responder");
            } catch (GeneralSecurityException ex) {
                signingCert = null;
            }
        }
    }
    if (signingCert == null) {
        throw new CertPathValidatorException("Unable to verify OCSP Response\'s signature");
    } else {
        if (!verifySignature(basicOcspResponse, signingCert)) {
            throw new CertPathValidatorException("Error verifying OCSP Response\'s signature");
        } else {
            Extension responseNonce = basicOcspResponse.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
            if (responseNonce != null && requestNonce != null && !Arrays.equals(requestNonce, responseNonce.getExtnValue().getOctets())) {
                throw new CertPathValidatorException("Nonces do not match.");
            } else {
                // See Sun's OCSP implementation.
                // https://www.ietf.org/rfc/rfc2560.txt, if nextUpdate is not set,
                // the responder is indicating that newer update is avilable all the time
                long current = date == null ? System.currentTimeMillis() : date.getTime();
                Date stop = new Date(current + (long) TIME_SKEW);
                Date start = new Date(current - (long) TIME_SKEW);
                Iterator<SingleResp> iter = Arrays.asList(basicOcspResponse.getResponses()).iterator();
                SingleResp singleRes = null;
                do {
                    if (!iter.hasNext()) {
                        return;
                    }
                    singleRes = iter.next();
                } while (!stop.before(singleRes.getThisUpdate()) && !start.after(singleRes.getNextUpdate() != null ? singleRes.getNextUpdate() : singleRes.getThisUpdate()));
                throw new CertPathValidatorException("Response is unreliable: its validity interval is out-of-date");
            }
        }
    }
}
Also used : JcaX509ExtensionUtils(org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils) GeneralSecurityException(java.security.GeneralSecurityException) X500Name(org.bouncycastle.asn1.x500.X500Name) SubjectKeyIdentifier(org.bouncycastle.asn1.x509.SubjectKeyIdentifier) JcaX509CertificateHolder(org.bouncycastle.cert.jcajce.JcaX509CertificateHolder) Extension(org.bouncycastle.asn1.x509.Extension) JcaX509CertificateConverter(org.bouncycastle.cert.jcajce.JcaX509CertificateConverter) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) JcaX509CertificateHolder(org.bouncycastle.cert.jcajce.JcaX509CertificateHolder)

Aggregations

BigInteger (java.math.BigInteger)12 X509Certificate (java.security.cert.X509Certificate)12 Date (java.util.Date)12 Time (org.bouncycastle.asn1.x509.Time)8 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)8 IOException (java.io.IOException)7 DEROctetString (org.bouncycastle.asn1.DEROctetString)7 X500Name (org.bouncycastle.asn1.x500.X500Name)7 ASN1GeneralizedTime (org.bouncycastle.asn1.ASN1GeneralizedTime)6 ASN1Integer (org.bouncycastle.asn1.ASN1Integer)6 Extension (org.bouncycastle.asn1.x509.Extension)6 ASN1EncodableVector (com.android.org.bouncycastle.asn1.ASN1EncodableVector)5 ASN1InputStream (com.android.org.bouncycastle.asn1.ASN1InputStream)5 ASN1Integer (com.android.org.bouncycastle.asn1.ASN1Integer)5 ASN1ObjectIdentifier (com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier)5 DERBitString (com.android.org.bouncycastle.asn1.DERBitString)5 DERInteger (com.android.org.bouncycastle.asn1.DERInteger)5 DERSequence (com.android.org.bouncycastle.asn1.DERSequence)5 AlgorithmIdentifier (com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier)5 TBSCertificate (com.android.org.bouncycastle.asn1.x509.TBSCertificate)5