Search in sources :

Example 6 with Time

use of org.spongycastle.asn1.x509.Time in project fdroidclient by f-droid.

the class LocalRepoKeyStore method generateSelfSignedCertChain.

private Certificate generateSelfSignedCertChain(KeyPair kp, X500Name subject, String hostname) throws CertificateException, OperatorCreationException, IOException {
    SecureRandom rand = new SecureRandom();
    PrivateKey privKey = kp.getPrivate();
    PublicKey pubKey = kp.getPublic();
    ContentSigner sigGen = new JcaContentSignerBuilder(DEFAULT_SIG_ALG).build(privKey);
    SubjectPublicKeyInfo subPubKeyInfo = new SubjectPublicKeyInfo(ASN1Sequence.getInstance(pubKey.getEncoded()));
    // now
    Date now = new Date();
    /* force it to use a English/Gregorian dates for the cert, hardly anyone
           ever looks at the cert metadata anyway, and its very likely that they
           understand English/Gregorian dates */
    Calendar c = new GregorianCalendar(Locale.ENGLISH);
    c.setTime(now);
    c.add(Calendar.YEAR, 1);
    Time startTime = new Time(now, Locale.ENGLISH);
    Time endTime = new Time(c.getTime(), Locale.ENGLISH);
    X509v3CertificateBuilder v3CertGen = new X509v3CertificateBuilder(subject, BigInteger.valueOf(rand.nextLong()), startTime, endTime, subject, subPubKeyInfo);
    if (hostname != null) {
        GeneralNames subjectAltName = new GeneralNames(new GeneralName(GeneralName.iPAddress, hostname));
        v3CertGen.addExtension(X509Extension.subjectAlternativeName, false, subjectAltName);
    }
    X509CertificateHolder certHolder = v3CertGen.build(sigGen);
    return new JcaX509CertificateConverter().getCertificate(certHolder);
}
Also used : PrivateKey(java.security.PrivateKey) PublicKey(java.security.PublicKey) JcaContentSignerBuilder(org.spongycastle.operator.jcajce.JcaContentSignerBuilder) Calendar(java.util.Calendar) GregorianCalendar(java.util.GregorianCalendar) ContentSigner(org.spongycastle.operator.ContentSigner) GregorianCalendar(java.util.GregorianCalendar) SecureRandom(java.security.SecureRandom) Time(org.spongycastle.asn1.x509.Time) SubjectPublicKeyInfo(org.spongycastle.asn1.x509.SubjectPublicKeyInfo) Date(java.util.Date) GeneralNames(org.spongycastle.asn1.x509.GeneralNames) X509v3CertificateBuilder(org.spongycastle.cert.X509v3CertificateBuilder) JcaX509CertificateConverter(org.spongycastle.cert.jcajce.JcaX509CertificateConverter) X509CertificateHolder(org.spongycastle.cert.X509CertificateHolder) GeneralName(org.spongycastle.asn1.x509.GeneralName)

Example 7 with Time

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

the class CRLUtils method check.

/**
 * Check the signature on CRL and check if 1st certificate from the chain ((The actual certificate from the client)) is valid and not available on CRL.
 *
 * @param certs The 1st certificate is the actual certificate of the user. The other certificates represents the certificate chain
 * @param crl Given CRL
 * @throws GeneralSecurityException if some error in validation happens. Typically certificate not valid, or CRL signature not valid
 */
public static void check(X509Certificate[] certs, X509CRL crl, KeycloakSession session) throws GeneralSecurityException {
    if (certs.length < 2) {
        throw new GeneralSecurityException("Not possible to verify signature on CRL. X509 certificate doesn't have CA chain available on it");
    }
    X500Principal crlIssuerPrincipal = crl.getIssuerX500Principal();
    X509Certificate crlSignatureCertificate = null;
    // Try to find the certificate in the CA chain, which was used to sign the CRL
    for (int i = 1; i < certs.length; i++) {
        X509Certificate currentCACert = certs[i];
        if (crlIssuerPrincipal.equals(currentCACert.getSubjectX500Principal())) {
            crlSignatureCertificate = currentCACert;
            log.tracef("Found certificate used to sign CRL in the CA chain of the certificate. CRL issuer: %s", crlIssuerPrincipal);
            break;
        }
    }
    // Try to find the CRL issuer certificate in the truststore
    if (crlSignatureCertificate == null) {
        log.tracef("Not found CRL issuer '%s' in the CA chain of the certificate. Fallback to lookup CRL issuer in the truststore", crlIssuerPrincipal);
        crlSignatureCertificate = findCRLSignatureCertificateInTruststore(session, certs, crlIssuerPrincipal);
    }
    // Verify signature on CRL
    // TODO: It will be nice to cache CRLs and also verify their signatures just once at the time when CRL is loaded, rather than in every request
    crl.verify(crlSignatureCertificate.getPublicKey());
    // Finally check if
    if (crl.isRevoked(certs[0])) {
        String message = String.format("Certificate has been revoked, certificate's subject: %s", certs[0].getSubjectDN().getName());
        log.debug(message);
        throw new GeneralSecurityException(message);
    }
}
Also used : GeneralSecurityException(java.security.GeneralSecurityException) X500Principal(javax.security.auth.x500.X500Principal) DEROctetString(org.bouncycastle.asn1.DEROctetString) DERIA5String(org.bouncycastle.asn1.DERIA5String) X509Certificate(java.security.cert.X509Certificate) DistributionPoint(org.bouncycastle.asn1.x509.DistributionPoint) CRLDistPoint(org.bouncycastle.asn1.x509.CRLDistPoint)

Example 8 with Time

use of org.spongycastle.asn1.x509.Time in project Spark by igniterealtime.

the class SparkTrustManager method validatePath.

/**
 * Validate certificate path
 *
 * @throws NoSuchAlgorithmException
 * @throws KeyStoreException
 * @throws InvalidAlgorithmParameterException
 * @throws CertPathValidatorException
 * @throws CertPathBuilderException
 * @throws CertificateException
 */
private void validatePath(X509Certificate[] chain) throws NoSuchAlgorithmException, KeyStoreException, InvalidAlgorithmParameterException, CertPathValidatorException, CertPathBuilderException, CertificateException {
    // PKIX algorithm is defined in rfc3280
    CertPathValidator certPathValidator = CertPathValidator.getInstance("PKIX");
    CertPathBuilder certPathBuilder = CertPathBuilder.getInstance("PKIX");
    X509CertSelector certSelector = new X509CertSelector();
    // set last certificate (often root CA) from chain for CertSelector so trust store must contain it
    certSelector.setCertificate(chain[chain.length - 1]);
    // checks against time validity aren't done here as are already done in checkDateValidity (X509Certificate[]
    // chain)
    certSelector.setCertificateValid(null);
    // create parameters using trustStore as source of Trust Anchors and using X509CertSelector
    PKIXBuilderParameters parameters = new PKIXBuilderParameters(allStore, certSelector);
    // will use PKIXRevocationChecker (or nothing if revocation mechanisms are
    // disabled) instead of the default revocation checker
    parameters.setRevocationEnabled(false);
    // certificates from blacklist will be rejected
    if (acceptRevoked == false) {
        // OCSP checking is done according to Java PKI Programmer's Guide, PKIXRevocationChecker was added in Java 8:
        // https://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html#PKIXRevocationChecker
        PKIXRevocationChecker checker = (PKIXRevocationChecker) certPathBuilder.getRevocationChecker();
        EnumSet<PKIXRevocationChecker.Option> checkerOptions = EnumSet.noneOf(PKIXRevocationChecker.Option.class);
        // is enabled then in case of network issues revocation checking is omitted
        if (allowSoftFail) {
            checkerOptions.add(PKIXRevocationChecker.Option.SOFT_FAIL);
        }
        // check OCSP, CRL serve as backup
        if (checkOCSP && checkCRL) {
            checker.setOptions(checkerOptions);
            parameters.addCertPathChecker(checker);
        } else if (!checkOCSP && checkCRL) {
            // check only CRL, if CRL fail then there is no fallback to OCSP
            checkerOptions.add(PKIXRevocationChecker.Option.PREFER_CRLS);
            checkerOptions.add(PKIXRevocationChecker.Option.NO_FALLBACK);
            checker.setOptions(checkerOptions);
            parameters.addCertPathChecker(checker);
        }
    }
    try {
        CertPathBuilderResult pathResult = certPathBuilder.build(parameters);
        CertPath certPath = pathResult.getCertPath();
        PKIXCertPathValidatorResult validationResult = (PKIXCertPathValidatorResult) certPathValidator.validate(certPath, parameters);
        X509Certificate trustedCert = validationResult.getTrustAnchor().getTrustedCert();
        if (trustedCert == null) {
            throw new CertificateException("certificate path failed: Trusted CA is NULL");
        }
        // this extension is last certificate: root CA
        for (int i = 0; i < chain.length - 1; i++) {
            checkBasicConstraints(chain[i]);
        }
    } catch (CertificateRevokedException e) {
        Log.warning("Certificate was revoked", e);
        for (X509Certificate cert : chain) {
            for (X509CRL crl : crlCollection) {
                if (crl.isRevoked(cert)) {
                    try {
                        addToBlackList(cert);
                    } catch (IOException | HeadlessException | InvalidNameException e1) {
                        Log.error("Couldn't move to the blacklist", e1);
                    }
                    break;
                }
            }
        }
        throw new CertificateException("Certificate was revoked");
    }
}
Also used : X509CRL(java.security.cert.X509CRL) PKIXBuilderParameters(java.security.cert.PKIXBuilderParameters) CertificateRevokedException(java.security.cert.CertificateRevokedException) CertPathBuilderResult(java.security.cert.CertPathBuilderResult) X509CertSelector(java.security.cert.X509CertSelector) CertificateException(java.security.cert.CertificateException) X509Certificate(java.security.cert.X509Certificate) DistributionPoint(org.bouncycastle.asn1.x509.DistributionPoint) CRLDistPoint(org.bouncycastle.asn1.x509.CRLDistPoint) CertPathValidator(java.security.cert.CertPathValidator) PKIXCertPathValidatorResult(java.security.cert.PKIXCertPathValidatorResult) PKIXRevocationChecker(java.security.cert.PKIXRevocationChecker) CertPathBuilder(java.security.cert.CertPathBuilder) CertPath(java.security.cert.CertPath)

Example 9 with Time

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

the class ImportCrl method addCertificate.

private void addCertificate(AtomicLong maxId, int caId, Certificate cert, String profileName, String certLogId) throws DataAccessException, ImportCrlException {
    // not issued by the given issuer
    if (!caSubject.equals(cert.getIssuer())) {
        LOG.warn("certificate {} is not issued by the given CA, ignore it", certLogId);
        return;
    }
    // we don't use the binary read from file, since it may contains redundant ending bytes.
    byte[] encodedCert;
    try {
        encodedCert = cert.getEncoded();
    } catch (IOException ex) {
        throw new ImportCrlException("could not encode certificate {}" + certLogId, ex);
    }
    String b64CertHash = certhashAlgo.base64Hash(encodedCert);
    if (caSpki != null) {
        byte[] aki = null;
        try {
            aki = X509Util.extractAki(cert);
        } catch (CertificateEncodingException ex) {
            LogUtil.error(LOG, ex, "invalid AuthorityKeyIdentifier of certificate {}" + certLogId + ", ignore it");
            return;
        }
        if (aki == null || !Arrays.equals(caSpki, aki)) {
            LOG.warn("certificate {} is not issued by the given CA, ignore it", certLogId);
            return;
        }
    }
    // end if
    LOG.info("Importing certificate {}", certLogId);
    Long id = getId(caId, cert.getSerialNumber().getPositiveValue());
    boolean tblCertIdExists = (id != null);
    PreparedStatement ps;
    String sql;
    // first update the table CERT
    if (tblCertIdExists) {
        sql = SQL_UPDATE_CERT;
        ps = psUpdateCert;
    } else {
        sql = SQL_INSERT_CERT;
        ps = psInsertCert;
        id = maxId.incrementAndGet();
    }
    try {
        int offset = 1;
        if (sql == SQL_INSERT_CERT) {
            ps.setLong(offset++, id);
            // ISSUER ID IID
            ps.setInt(offset++, caId);
            // serial number SN
            ps.setString(offset++, cert.getSerialNumber().getPositiveValue().toString(16));
            // whether revoked REV
            ps.setInt(offset++, 0);
            // revocation reason RR
            ps.setNull(offset++, Types.SMALLINT);
            // revocation time RT
            ps.setNull(offset++, Types.BIGINT);
            ps.setNull(offset++, Types.BIGINT);
        }
        // last update LUPDATE
        ps.setLong(offset++, System.currentTimeMillis() / 1000);
        TBSCertificate tbsCert = cert.getTBSCertificate();
        // not before NBEFORE
        ps.setLong(offset++, tbsCert.getStartDate().getDate().getTime() / 1000);
        // not after NAFTER
        ps.setLong(offset++, tbsCert.getEndDate().getDate().getTime() / 1000);
        // profile name PN
        if (StringUtil.isBlank(profileName)) {
            ps.setNull(offset++, Types.VARCHAR);
        } else {
            ps.setString(offset++, profileName);
        }
        ps.setString(offset++, b64CertHash);
        if (sql == SQL_UPDATE_CERT) {
            ps.setLong(offset++, id);
        }
        ps.executeUpdate();
    } catch (SQLException ex) {
        throw datasource.translate(sql, ex);
    }
    // it is not required to add entry to table CRAW
    LOG.info("Imported  certificate {}", certLogId);
}
Also used : SQLException(java.sql.SQLException) AtomicLong(java.util.concurrent.atomic.AtomicLong) CertificateEncodingException(java.security.cert.CertificateEncodingException) PreparedStatement(java.sql.PreparedStatement) IOException(java.io.IOException) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DEROctetString(org.bouncycastle.asn1.DEROctetString) DERIA5String(org.bouncycastle.asn1.DERIA5String) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) TBSCertificate(org.bouncycastle.asn1.x509.TBSCertificate)

Example 10 with Time

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

the class OcspQa method checkSingleCert.

// method checkOcsp
private List<ValidationIssue> checkSingleCert(int index, SingleResp singleResp, IssuerHash issuerHash, OcspCertStatus expectedStatus, byte[] encodedCert, Date expectedRevTime, boolean extendedRevoke, Occurrence nextupdateOccurrence, Occurrence certhashOccurrence, ASN1ObjectIdentifier certhashAlg) {
    if (expectedStatus == OcspCertStatus.unknown || expectedStatus == OcspCertStatus.issuerUnknown) {
        certhashOccurrence = Occurrence.forbidden;
    }
    List<ValidationIssue> issues = new LinkedList<>();
    // issuer hash
    ValidationIssue issue = new ValidationIssue("OCSP.RESPONSE." + index + ".ISSUER", "certificate issuer");
    issues.add(issue);
    CertificateID certId = singleResp.getCertID();
    HashAlgo hashAlgo = HashAlgo.getInstance(certId.getHashAlgOID());
    if (hashAlgo == null) {
        issue.setFailureMessage("unknown hash algorithm " + certId.getHashAlgOID().getId());
    } else {
        if (!issuerHash.match(hashAlgo, certId.getIssuerNameHash(), certId.getIssuerKeyHash())) {
            issue.setFailureMessage("issuer not match");
        }
    }
    // status
    issue = new ValidationIssue("OCSP.RESPONSE." + index + ".STATUS", "certificate status");
    issues.add(issue);
    CertificateStatus singleCertStatus = singleResp.getCertStatus();
    OcspCertStatus status = null;
    Long revTimeSec = null;
    if (singleCertStatus == null) {
        status = OcspCertStatus.good;
    } else if (singleCertStatus instanceof RevokedStatus) {
        RevokedStatus revStatus = (RevokedStatus) singleCertStatus;
        revTimeSec = revStatus.getRevocationTime().getTime() / 1000;
        if (revStatus.hasRevocationReason()) {
            int reason = revStatus.getRevocationReason();
            if (extendedRevoke && reason == CrlReason.CERTIFICATE_HOLD.getCode() && revTimeSec == 0) {
                status = OcspCertStatus.unknown;
                revTimeSec = null;
            } else {
                CrlReason revocationReason = CrlReason.forReasonCode(reason);
                switch(revocationReason) {
                    case UNSPECIFIED:
                        status = OcspCertStatus.unspecified;
                        break;
                    case KEY_COMPROMISE:
                        status = OcspCertStatus.keyCompromise;
                        break;
                    case CA_COMPROMISE:
                        status = OcspCertStatus.cACompromise;
                        break;
                    case AFFILIATION_CHANGED:
                        status = OcspCertStatus.affiliationChanged;
                        break;
                    case SUPERSEDED:
                        status = OcspCertStatus.superseded;
                        break;
                    case CERTIFICATE_HOLD:
                        status = OcspCertStatus.certificateHold;
                        break;
                    case REMOVE_FROM_CRL:
                        status = OcspCertStatus.removeFromCRL;
                        break;
                    case PRIVILEGE_WITHDRAWN:
                        status = OcspCertStatus.privilegeWithdrawn;
                        break;
                    case AA_COMPROMISE:
                        status = OcspCertStatus.aACompromise;
                        break;
                    case CESSATION_OF_OPERATION:
                        status = OcspCertStatus.cessationOfOperation;
                        break;
                    default:
                        issue.setFailureMessage("should not reach here, unknown CRLReason " + revocationReason);
                        break;
                }
            }
        // end if
        } else {
            status = OcspCertStatus.rev_noreason;
        }
    // end if (revStatus.hasRevocationReason())
    } else if (singleCertStatus instanceof UnknownStatus) {
        status = extendedRevoke ? OcspCertStatus.issuerUnknown : OcspCertStatus.unknown;
    } else {
        issue.setFailureMessage("unknown certstatus: " + singleCertStatus.getClass().getName());
    }
    if (!issue.isFailed() && expectedStatus != status) {
        issue.setFailureMessage("is='" + status + "', but expected='" + expectedStatus + "'");
    }
    // revocation time
    issue = new ValidationIssue("OCSP.RESPONSE." + index + ".REVTIME", "certificate time");
    issues.add(issue);
    if (expectedRevTime != null) {
        if (revTimeSec == null) {
            issue.setFailureMessage("is='null', but expected='" + formatTime(expectedRevTime) + "'");
        } else if (revTimeSec != expectedRevTime.getTime() / 1000) {
            issue.setFailureMessage("is='" + formatTime(new Date(revTimeSec * 1000)) + "', but expected='" + formatTime(expectedRevTime) + "'");
        }
    }
    // nextUpdate
    Date nextUpdate = singleResp.getNextUpdate();
    issue = checkOccurrence("OCSP.RESPONSE." + index + ".NEXTUPDATE", nextUpdate, nextupdateOccurrence);
    issues.add(issue);
    Extension extension = singleResp.getExtension(ISISMTTObjectIdentifiers.id_isismtt_at_certHash);
    issue = checkOccurrence("OCSP.RESPONSE." + index + ".CERTHASH", extension, certhashOccurrence);
    issues.add(issue);
    if (extension != null) {
        ASN1Encodable extensionValue = extension.getParsedValue();
        CertHash certHash = CertHash.getInstance(extensionValue);
        ASN1ObjectIdentifier hashAlgOid = certHash.getHashAlgorithm().getAlgorithm();
        if (certhashAlg != null) {
            // certHash algorithm
            issue = new ValidationIssue("OCSP.RESPONSE." + index + ".CHASH.ALG", "certhash algorithm");
            issues.add(issue);
            ASN1ObjectIdentifier is = certHash.getHashAlgorithm().getAlgorithm();
            if (!certhashAlg.equals(is)) {
                issue.setFailureMessage("is '" + is.getId() + "', but expected '" + certhashAlg.getId() + "'");
            }
        }
        byte[] hashValue = certHash.getCertificateHash();
        if (encodedCert != null) {
            issue = new ValidationIssue("OCSP.RESPONSE." + index + ".CHASH.VALIDITY", "certhash validity");
            issues.add(issue);
            try {
                MessageDigest md = MessageDigest.getInstance(hashAlgOid.getId());
                byte[] expectedHashValue = md.digest(encodedCert);
                if (!Arrays.equals(expectedHashValue, hashValue)) {
                    issue.setFailureMessage("certhash does not match the requested certificate");
                }
            } catch (NoSuchAlgorithmException ex) {
                issue.setFailureMessage("NoSuchAlgorithm " + hashAlgOid.getId());
            }
        }
    // end if(encodedCert != null)
    }
    return issues;
}
Also used : CertHash(org.bouncycastle.asn1.isismtt.ocsp.CertHash) CertificateID(org.bouncycastle.cert.ocsp.CertificateID) HashAlgo(org.xipki.security.HashAlgo) CertificateStatus(org.bouncycastle.cert.ocsp.CertificateStatus) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ValidationIssue(org.xipki.common.qa.ValidationIssue) LinkedList(java.util.LinkedList) Date(java.util.Date) UnknownStatus(org.bouncycastle.cert.ocsp.UnknownStatus) Extension(org.bouncycastle.asn1.x509.Extension) RevokedStatus(org.bouncycastle.cert.ocsp.RevokedStatus) CrlReason(org.xipki.security.CrlReason) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) MessageDigest(java.security.MessageDigest) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

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