List of usage examples for java.security.cert X509Certificate getExtensionValue
public byte[] getExtensionValue(String oid);
From source file:org.cesecore.util.CertTools.java
/** * Get a certificate policy ID from a certificate policies extension * /*w w w . j ava 2 s . c o m*/ * @param cert certificate containing the extension * @param pos position of the policy id, if several exist, the first is as pos 0 * @return String with the certificate policy OID, or null if an id at the given position does not exist * @throws IOException if extension can not be parsed */ public static String getCertificatePolicyId(Certificate cert, int pos) throws IOException { String ret = null; if (cert instanceof X509Certificate) { X509Certificate x509cert = (X509Certificate) cert; byte[] extvalue = x509cert.getExtensionValue(Extension.certificatePolicies.getId()); if (extvalue == null) { return null; } ASN1InputStream extAsn1InputStream = new ASN1InputStream(new ByteArrayInputStream(extvalue)); try { DEROctetString oct = (DEROctetString) (extAsn1InputStream.readObject()); ASN1InputStream octAsn1InputStream = new ASN1InputStream(new ByteArrayInputStream(oct.getOctets())); try { ASN1Sequence seq = (ASN1Sequence) octAsn1InputStream.readObject(); // Check the size so we don't ArrayIndexOutOfBounds if (seq.size() < pos + 1) { return null; } PolicyInformation pol = PolicyInformation.getInstance((ASN1Sequence) seq.getObjectAt(pos)); ret = pol.getPolicyIdentifier().getId(); } finally { octAsn1InputStream.close(); } } finally { extAsn1InputStream.close(); } } return ret; }
From source file:org.cesecore.util.CertTools.java
/** * Get the subject key identifier from a certificate extensions * /*from w w w . j a v a 2s. c o m*/ * @param cert certificate containing the extension * @return byte[] containing the subject key identifier, or null if it does not exist */ public static byte[] getSubjectKeyId(Certificate cert) { if (cert == null) { return null; } if (cert instanceof X509Certificate) { X509Certificate x509cert = (X509Certificate) cert; byte[] extvalue = x509cert.getExtensionValue("2.5.29.14"); if (extvalue == null) { return null; } ASN1InputStream extvalueAsn1InputStream = new ASN1InputStream(new ByteArrayInputStream(extvalue)); try { try { ASN1OctetString str = ASN1OctetString.getInstance(extvalueAsn1InputStream.readObject()); ASN1InputStream strAsn1InputStream = new ASN1InputStream( new ByteArrayInputStream(str.getOctets())); try { SubjectKeyIdentifier keyId = SubjectKeyIdentifier .getInstance(strAsn1InputStream.readObject()); return keyId.getKeyIdentifier(); } finally { strAsn1InputStream.close(); } } finally { extvalueAsn1InputStream.close(); } } catch (IOException e) { throw new IllegalStateException("Could not parse subject key ID from certificate.", e); } } return null; }
From source file:org.cesecore.util.CertTools.java
/** * Get the authority key identifier from a certificate extensions * /*ww w .j av a 2 s.c o m*/ * @param cert certificate containing the extension * @return byte[] containing the authority key identifier, or null if it does not exist */ public static byte[] getAuthorityKeyId(Certificate cert) { if (cert == null) { return null; } if (cert instanceof X509Certificate) { X509Certificate x509cert = (X509Certificate) cert; byte[] extvalue = x509cert.getExtensionValue("2.5.29.35"); if (extvalue == null) { return null; } try { ASN1InputStream octAsn1InputStream = new ASN1InputStream(new ByteArrayInputStream(extvalue)); try { DEROctetString oct = (DEROctetString) (octAsn1InputStream.readObject()); ASN1InputStream keyAsn1InputStream = new ASN1InputStream( new ByteArrayInputStream(oct.getOctets())); try { AuthorityKeyIdentifier keyId = AuthorityKeyIdentifier .getInstance((ASN1Sequence) keyAsn1InputStream.readObject()); return keyId.getKeyIdentifier(); } finally { keyAsn1InputStream.close(); } } finally { octAsn1InputStream.close(); } } catch (IOException e) { throw new IllegalStateException("Could not parse authority key identifier from certificate.", e); } } return null; }
From source file:org.cesecore.util.CertTools.java
/** * //from w ww .j a v a 2 s .c o m * @param cert An X509Certificate * @param oid An OID for an extension * @return an Extension ASN1Primitive from a certificate */ protected static ASN1Primitive getExtensionValue(X509Certificate cert, String oid) { if (cert == null) { return null; } byte[] bytes = cert.getExtensionValue(oid); return getDerObjectFromByteArray(bytes); }
From source file:org.cesecore.util.CertTools.java
/** Reads PrivateKeyUsagePeriod extension from a certificate * /* w w w. j a v a 2 s .c o m*/ */ public static PrivateKeyUsagePeriod getPrivateKeyUsagePeriod(final X509Certificate cert) { PrivateKeyUsagePeriod res = null; final byte[] extvalue = cert.getExtensionValue(Extension.privateKeyUsagePeriod.getId()); if ((extvalue != null) && (extvalue.length > 0)) { if (log.isTraceEnabled()) { log.trace("Found a PrivateKeyUsagePeriod in the certificate with subject: " + cert.getSubjectDN().toString()); } ASN1InputStream extAsn1InputStream = new ASN1InputStream(new ByteArrayInputStream(extvalue)); try { try { final DEROctetString oct = (DEROctetString) (extAsn1InputStream.readObject()); ASN1InputStream octAsn1InputStream = new ASN1InputStream( new ByteArrayInputStream(oct.getOctets())); try { res = PrivateKeyUsagePeriod.getInstance((ASN1Sequence) octAsn1InputStream.readObject()); } finally { octAsn1InputStream.close(); } } finally { extAsn1InputStream.close(); } } catch (IOException e) { throw new IllegalStateException("Unknown IOException caught when trying to parse certificate.", e); } } return res; }
From source file:org.cesecore.util.CertTools.java
/** * Checks that the given SubjectDN / SAN satisfies the Name Constraints of the given issuer (if there are any). * This method checks the Name Constraints in the given issuer only. A complete implementation of * name constraints should check the whole certificate chain. * //from w ww.j a va2 s .co m * @param issuer Issuing CA. * @param subjectDNName Subject DN to check. Optional. * @param subjectAltName Subject Alternative Name to check. Optional. * @throws CertificateExtensionException */ public static void checkNameConstraints(X509Certificate issuer, X500Name subjectDNName, GeneralNames subjectAltName) throws IllegalNameException { final byte[] ncbytes = issuer.getExtensionValue(Extension.nameConstraints.getId()); final ASN1OctetString ncstr = (ncbytes != null ? DEROctetString.getInstance(ncbytes) : null); final ASN1Sequence ncseq = (ncbytes != null ? DERSequence.getInstance(ncstr.getOctets()) : null); final NameConstraints nc = (ncseq != null ? NameConstraints.getInstance(ncseq) : null); if (nc != null) { if (subjectDNName != null) { // Skip check for root CAs final X500Name issuerDNName = X500Name.getInstance(issuer.getSubjectX500Principal().getEncoded()); if (issuerDNName.equals(subjectDNName)) { return; } } final PKIXNameConstraintValidator validator = new PKIXNameConstraintValidator(); GeneralSubtree[] permitted = nc.getPermittedSubtrees(); GeneralSubtree[] excluded = nc.getExcludedSubtrees(); if (permitted != null) { validator.intersectPermittedSubtree(permitted); } if (excluded != null) { for (GeneralSubtree subtree : excluded) { validator.addExcludedSubtree(subtree); } } if (subjectDNName != null) { GeneralName dngn = new GeneralName(subjectDNName); try { validator.checkPermitted(dngn); validator.checkExcluded(dngn); } catch (PKIXNameConstraintValidatorException e) { final String dnStr = subjectDNName.toString(); final boolean isLdapOrder = dnHasMultipleComponents(dnStr) && !isDNReversed(dnStr); if (isLdapOrder) { final String msg = intres.getLocalizedMessage("nameconstraints.x500dnorderrequired"); throw new IllegalNameException(msg); } else { final String msg = intres.getLocalizedMessage("nameconstraints.forbiddensubjectdn", subjectDNName); throw new IllegalNameException(msg, e); } } } if (subjectAltName != null) { for (GeneralName sangn : subjectAltName.getNames()) { try { validator.checkPermitted(sangn); validator.checkExcluded(sangn); } catch (PKIXNameConstraintValidatorException e) { final String msg = intres.getLocalizedMessage("nameconstraints.forbiddensubjectaltname", sangn); throw new IllegalNameException(msg, e); } } } } }
From source file:be.fedict.trust.ocsp.OcspTrustLinker.java
public TrustLinkerResult hasTrustLink(X509Certificate childCertificate, X509Certificate certificate, Date validationDate, RevocationData revocationData) { URI ocspUri = getOcspUri(childCertificate); if (null == ocspUri) { return null; }/*from ww w . j a va 2s .c o m*/ LOG.debug("OCSP URI: " + ocspUri); OCSPResp ocspResp = this.ocspRepository.findOcspResponse(ocspUri, childCertificate, certificate); if (null == ocspResp) { LOG.debug("OCSP response not found"); return null; } int ocspRespStatus = ocspResp.getStatus(); if (OCSPResponseStatus.SUCCESSFUL != ocspRespStatus) { LOG.debug("OCSP response status: " + ocspRespStatus); return null; } Object responseObject; try { responseObject = ocspResp.getResponseObject(); } catch (OCSPException e) { LOG.debug("OCSP exception: " + e.getMessage(), e); return null; } BasicOCSPResp basicOCSPResp = (BasicOCSPResp) responseObject; try { X509Certificate[] responseCertificates = basicOCSPResp.getCerts(BouncyCastleProvider.PROVIDER_NAME); for (X509Certificate responseCertificate : responseCertificates) { LOG.debug("OCSP response cert: " + responseCertificate.getSubjectX500Principal()); LOG.debug("OCSP response cert issuer: " + responseCertificate.getIssuerX500Principal()); } TrustLinkerResult trustResult = TrustValidator .checkSignatureAlgorithm(basicOCSPResp.getSignatureAlgName()); if (!trustResult.isValid()) return trustResult; if (0 == responseCertificates.length) { /* * This means that the OCSP response has been signed by the * issuing CA itself. */ boolean verificationResult = basicOCSPResp.verify(certificate.getPublicKey(), BouncyCastleProvider.PROVIDER_NAME); if (false == verificationResult) { LOG.debug("OCSP response signature invalid"); return null; } } else { /* * We're dealing with a dedicated authorized OCSP Responder * certificate, or of course with a CA that issues the OCSP * Responses itself. */ X509Certificate ocspResponderCertificate = responseCertificates[0]; boolean verificationResult = basicOCSPResp.verify(ocspResponderCertificate.getPublicKey(), BouncyCastleProvider.PROVIDER_NAME); if (false == verificationResult) { LOG.debug("OCSP Responser response signature invalid"); return null; } if (false == Arrays.equals(certificate.getEncoded(), ocspResponderCertificate.getEncoded())) { // check certificate signature trustResult = TrustValidator.checkSignatureAlgorithm(ocspResponderCertificate.getSigAlgName()); if (!trustResult.isValid()) { return trustResult; } X509Certificate issuingCaCertificate; if (responseCertificates.length < 2) { LOG.debug("OCSP responder complete certificate chain missing"); /* * Here we assume that the OCSP Responder is directly * signed by the CA. */ issuingCaCertificate = certificate; } else { issuingCaCertificate = responseCertificates[1]; /* * Is next check really required? */ if (false == certificate.equals(issuingCaCertificate)) { LOG.debug("OCSP responder certificate not issued by CA"); return null; } } // check certificate signature trustResult = TrustValidator.checkSignatureAlgorithm(issuingCaCertificate.getSigAlgName()); if (!trustResult.isValid()) { return trustResult; } PublicKeyTrustLinker publicKeyTrustLinker = new PublicKeyTrustLinker(); trustResult = publicKeyTrustLinker.hasTrustLink(ocspResponderCertificate, issuingCaCertificate, validationDate, revocationData); if (null != trustResult) { if (!trustResult.isValid()) { LOG.debug("OCSP responder not trusted"); return null; } } if (null == ocspResponderCertificate .getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck.getId())) { LOG.debug("OCSP Responder certificate should have id-pkix-ocsp-nocheck"); /* * TODO: perform CRL validation on the OCSP Responder * certificate. On the other hand, do we really want to * check the checker? */ return null; } List<String> extendedKeyUsage; try { extendedKeyUsage = ocspResponderCertificate.getExtendedKeyUsage(); } catch (CertificateParsingException e) { LOG.debug("OCSP Responder parsing error: " + e.getMessage(), e); return null; } if (null == extendedKeyUsage) { LOG.debug("OCSP Responder certificate has no extended key usage extension"); return null; } if (false == extendedKeyUsage.contains(KeyPurposeId.id_kp_OCSPSigning.getId())) { LOG.debug("OCSP Responder certificate should have a OCSPSigning extended key usage"); return null; } } else { LOG.debug("OCSP Responder certificate equals the CA certificate"); } } } catch (NoSuchProviderException e) { LOG.debug("JCA provider exception: " + e.getMessage(), e); return null; } catch (OCSPException e) { LOG.debug("OCSP exception: " + e.getMessage(), e); return null; } catch (CertificateEncodingException e) { LOG.debug("certificate encoding error: " + e.getMessage(), e); return null; } CertificateID certificateId; try { certificateId = new CertificateID(CertificateID.HASH_SHA1, certificate, childCertificate.getSerialNumber()); } catch (OCSPException e) { LOG.debug("OCSP exception: " + e.getMessage(), e); return null; } SingleResp[] singleResps = basicOCSPResp.getResponses(); for (SingleResp singleResp : singleResps) { CertificateID responseCertificateId = singleResp.getCertID(); if (false == certificateId.equals(responseCertificateId)) { continue; } Date thisUpdate = singleResp.getThisUpdate(); LOG.debug("OCSP thisUpdate: " + thisUpdate); LOG.debug("OCSP nextUpdate: " + singleResp.getNextUpdate()); long dt = Math.abs(thisUpdate.getTime() - validationDate.getTime()); if (dt > this.freshnessInterval) { LOG.warn("freshness interval exceeded: " + dt + " milliseconds"); continue; } if (null == singleResp.getCertStatus()) { LOG.debug("OCSP OK for: " + childCertificate.getSubjectX500Principal()); addRevocationData(revocationData, ocspResp); return new TrustLinkerResult(true); } else { LOG.debug("OCSP certificate status: " + singleResp.getCertStatus().getClass().getName()); if (singleResp.getCertStatus() instanceof RevokedStatus) { LOG.debug("OCSP status revoked"); } addRevocationData(revocationData, ocspResp); return new TrustLinkerResult(false, TrustLinkerResultReason.INVALID_REVOCATION_STATUS, "certificate revoked by OCSP"); } } LOG.debug("no matching OCSP response entry"); return null; }
From source file:org.ejbca.core.protocol.ws.CommonEjbcaWS.java
/** * Test method for creating/editing a user a requesting a certificate in a single transaction. *///from w ww .j a v a 2 s.c o m protected void certificateRequest() throws Exception { final UserDataVOWS userData1 = getUserData(CA1_WSTESTUSER1); ErrorCode errorCode = certreqInternal(userData1, getP10(), CertificateHelper.CERT_REQ_TYPE_PKCS10); assertNull("PKCS#10 request resulted in error code: " + (errorCode == null ? "" : errorCode.getInternalErrorCode()), errorCode); errorCode = certreqInternal(userData1, CRMF, CertificateHelper.CERT_REQ_TYPE_CRMF); assertNull("CRMF request resulted in error code: " + (errorCode == null ? "" : errorCode.getInternalErrorCode()), errorCode); errorCode = certreqInternal(userData1, SPCAK, CertificateHelper.CERT_REQ_TYPE_SPKAC); assertNull("SPKAC request resulted in error code: " + (errorCode == null ? "" : errorCode.getInternalErrorCode()), errorCode); errorCode = certreqInternal(userData1, PUBLICKEY_PEM, CertificateHelper.CERT_REQ_TYPE_PUBLICKEY); assertNull("PUBLICKEY request resulted in error code: " + (errorCode == null ? "" : errorCode.getInternalErrorCode()), errorCode); errorCode = certreqInternal(userData1, PUBLICKEY_BASE64, CertificateHelper.CERT_REQ_TYPE_PUBLICKEY); assertNull("PUBLICKEY request resulted in error code: " + (errorCode == null ? "" : errorCode.getInternalErrorCode()), errorCode); // Test with custom extensions final AuthenticationToken admin = new TestAlwaysAllowLocalAuthenticationToken( new UsernamePrincipal("SYSTEMTEST")); userData1.setStatus(UserDataVOWS.STATUS_NEW); userData1.setTokenType(UserDataVOWS.TOKEN_TYPE_USERGENERATED); userData1.setEndEntityProfileName(WS_EEPROF_EI); userData1.setCertificateProfileName(WS_CERTPROF_EI); ejbcaraws.editUser(userData1); CertificateResponse certificateResponse = ejbcaraws.certificateRequest(userData1, getP10(), CertificateHelper.CERT_REQ_TYPE_PKCS10, null, CertificateHelper.RESPONSETYPE_CERTIFICATE); X509Certificate cert = certificateResponse.getCertificate(); byte[] ext = cert.getExtensionValue("1.2.3.4"); // Certificate profile did not allow extension override assertNull("no extension should exist", ext); // Allow extension override CertificateProfile profile = certificateProfileSession.getCertificateProfile(WS_CERTPROF_EI); profile.setAllowExtensionOverride(true); certificateProfileSession.changeCertificateProfile(admin, WS_CERTPROF_EI, profile); // Now our extension should be possible to get in there try { ejbcaraws.editUser(userData1); certificateResponse = ejbcaraws.certificateRequest(userData1, getP10(), CertificateHelper.CERT_REQ_TYPE_PKCS10, null, CertificateHelper.RESPONSETYPE_CERTIFICATE); cert = certificateResponse.getCertificate(); assertNotNull(cert); assertEquals(getDN(CA1_WSTESTUSER1), cert.getSubjectDN().toString()); ext = cert.getExtensionValue("1.2.3.4"); assertNotNull("there should be an extension", ext); ASN1InputStream asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(ext)); try { DEROctetString oct = (DEROctetString) (asn1InputStream.readObject()); assertEquals("Extension did not have the correct value", "foo123", (new String(oct.getOctets())).trim()); } finally { asn1InputStream.close(); } } finally { // restore profile.setAllowExtensionOverride(false); certificateProfileSession.changeCertificateProfile(admin, WS_CERTPROF_EI, profile); } // Make a test with EV TLS DN components try { final UserDataVOWS userData2 = getUserData(CA1_WSTESTUSER1); userData2.setUsername("EVTLSEJBCAWSTEST"); userData2.setSubjectDN( "CN=EVTLSEJBCAWSTEST,JurisdictionCountry=DE,JurisdictionState=Stockholm,JurisdictionLocality=Solna"); try { certificateResponse = ejbcaraws.certificateRequest(userData2, getP10(), CertificateHelper.CERT_REQ_TYPE_PKCS10, null, CertificateHelper.RESPONSETYPE_CERTIFICATE); } catch (EjbcaException_Exception e) { errorCode = e.getFaultInfo().getErrorCode(); log.info(errorCode.getInternalErrorCode(), e); assertNotNull("error code should not be null", errorCode); fail("certificate request with EV TLS DN components failed with error code " + errorCode.getInternalErrorCode()); } // Verify that the response is of the right type assertNotNull(certificateResponse); assertTrue(certificateResponse.getResponseType().equals(CertificateHelper.RESPONSETYPE_CERTIFICATE)); // Verify that the certificate in the response has the same Subject DN // as in the request. cert = certificateResponse.getCertificate(); assertNotNull(cert); assertEquals( "JurisdictionCountry=DE,JurisdictionState=Stockholm,JurisdictionLocality=Solna,CN=EVTLSEJBCAWSTEST", CertTools.getSubjectDN(cert)); } finally { // Clean up immediately endEntityManagementSession.deleteUser(admin, "EVTLSEJBCAWSTEST"); internalCertStoreSession.removeCertificate(CertTools.getFingerprintAsString(cert)); } }
From source file:org.ejbca.core.protocol.ws.CommonEjbcaWS.java
protected void generatePkcs10() throws Exception { UserDataVOWS user1 = new UserDataVOWS(); user1.setUsername(CA1_WSTESTUSER1);/*from w w w. j ava 2s . co m*/ user1.setPassword(PASSWORD); user1.setClearPwd(true); user1.setSubjectDN(getDN(CA1_WSTESTUSER1)); user1.setCaName(CA1); user1.setStatus(UserDataVOWS.STATUS_NEW); user1.setTokenType(UserDataVOWS.TOKEN_TYPE_USERGENERATED); user1.setEndEntityProfileName(WS_EEPROF_EI); user1.setCertificateProfileName(WS_CERTPROF_EI); ejbcaraws.editUser(user1); final AuthenticationToken admin = new TestAlwaysAllowLocalAuthenticationToken( new UsernamePrincipal("SYSTEMTEST")); PKCS10CertificationRequest pkcs10 = getP10Request(); // Submit the request CertificateResponse certenv = ejbcaraws.pkcs10Request(CA1_WSTESTUSER1, PASSWORD, new String(Base64.encode(pkcs10.getEncoded())), null, CertificateHelper.RESPONSETYPE_CERTIFICATE); assertNotNull(certenv); X509Certificate cert = (X509Certificate) CertificateHelper.getCertificate(certenv.getData()); assertNotNull(cert); assertEquals(getDN(CA1_WSTESTUSER1), cert.getSubjectDN().toString()); byte[] ext = cert.getExtensionValue("1.2.3.4"); // Certificate profile did not allow extension override assertNull("no extension should exist", ext); // Allow extension override CertificateProfile profile = certificateProfileSession.getCertificateProfile(WS_CERTPROF_EI); profile.setAllowExtensionOverride(true); certificateProfileSession.changeCertificateProfile(admin, WS_CERTPROF_EI, profile); // Now our extension should be possible to get in there try { ejbcaraws.editUser(user1); pkcs10 = getP10Request(); certenv = ejbcaraws.pkcs10Request(CA1_WSTESTUSER1, PASSWORD, new String(Base64.encode(pkcs10.getEncoded())), null, CertificateHelper.RESPONSETYPE_CERTIFICATE); assertNotNull(certenv); cert = (X509Certificate) CertificateHelper.getCertificate(certenv.getData()); assertNotNull(cert); assertEquals(getDN(CA1_WSTESTUSER1), cert.getSubjectDN().toString()); ext = cert.getExtensionValue("1.2.3.4"); assertNotNull("there should be an extension", ext); ASN1InputStream asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(ext)); try { DEROctetString oct = (DEROctetString) (asn1InputStream.readObject()); assertEquals("Extension did not have the correct value", "foo123", (new String(oct.getOctets())).trim()); } finally { asn1InputStream.close(); } } finally { // restore profile.setAllowExtensionOverride(false); certificateProfileSession.changeCertificateProfile(admin, WS_CERTPROF_EI, profile); } }
From source file:be.fedict.trust.PublicKeyTrustLinker.java
public TrustLinkerResult hasTrustLink(X509Certificate childCertificate, X509Certificate certificate, Date validationDate, RevocationData revocationData) { if (false == childCertificate.getIssuerX500Principal().equals(certificate.getSubjectX500Principal())) { LOG.debug("child certificate issuer not the same as the issuer certificate subject"); LOG.debug("child certificate: " + childCertificate.getSubjectX500Principal()); LOG.debug("certificate: " + certificate.getSubjectX500Principal()); LOG.debug("child certificate issuer: " + childCertificate.getIssuerX500Principal()); return new TrustLinkerResult(false, TrustLinkerResultReason.INVALID_TRUST, "child certificate issuer not the same as the issuer certificate subject"); }/* w w w . ja v a2 s. co m*/ try { childCertificate.verify(certificate.getPublicKey()); } catch (Exception e) { LOG.debug("verification error: " + e.getMessage(), e); return new TrustLinkerResult(false, TrustLinkerResultReason.INVALID_SIGNATURE, "verification error: " + e.getMessage()); } if (true == childCertificate.getNotAfter().after(certificate.getNotAfter())) { LOG.warn("child certificate validity end is after certificate validity end"); LOG.warn("child certificate validity end: " + childCertificate.getNotAfter()); LOG.warn("certificate validity end: " + certificate.getNotAfter()); } if (true == childCertificate.getNotBefore().before(certificate.getNotBefore())) { LOG.warn("child certificate validity begin before certificate validity begin"); LOG.warn("child certificate validity begin: " + childCertificate.getNotBefore()); LOG.warn("certificate validity begin: " + certificate.getNotBefore()); } if (true == validationDate.before(childCertificate.getNotBefore())) { LOG.debug("certificate is not yet valid"); return new TrustLinkerResult(false, TrustLinkerResultReason.INVALID_VALIDITY_INTERVAL, "certificate is not yet valid"); } if (true == validationDate.after(childCertificate.getNotAfter())) { LOG.debug("certificate already expired"); return new TrustLinkerResult(false, TrustLinkerResultReason.INVALID_VALIDITY_INTERVAL, "certificate already expired"); } if (-1 == certificate.getBasicConstraints()) { LOG.debug("certificate not a CA"); return new TrustLinkerResult(false, TrustLinkerResultReason.INVALID_TRUST, "certificate not a CA"); } if (0 == certificate.getBasicConstraints() && -1 != childCertificate.getBasicConstraints()) { LOG.debug("child should not be a CA"); return new TrustLinkerResult(false, TrustLinkerResultReason.INVALID_TRUST, "child should not be a CA"); } /* * SKID/AKID sanity check */ boolean isCa = isCa(certificate); boolean isChildCa = isCa(childCertificate); byte[] subjectKeyIdentifierData = certificate .getExtensionValue(X509Extensions.SubjectKeyIdentifier.getId()); byte[] authorityKeyIdentifierData = childCertificate .getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); if (isCa && null == subjectKeyIdentifierData) { LOG.debug("certificate is CA and MUST contain a Subject Key Identifier"); return new TrustLinkerResult(false, TrustLinkerResultReason.INVALID_TRUST, "certificate is CA and MUST contain a Subject Key Identifier"); } if (isChildCa && null == authorityKeyIdentifierData) { LOG.debug("child certificate is CA and MUST contain an Authority Key Identifier"); return new TrustLinkerResult(false, TrustLinkerResultReason.INVALID_TRUST, "child certificate is CA and MUST contain an Authority Key Identifier"); } if (null != subjectKeyIdentifierData && null != authorityKeyIdentifierData) { AuthorityKeyIdentifierStructure authorityKeyIdentifierStructure; try { authorityKeyIdentifierStructure = new AuthorityKeyIdentifierStructure(authorityKeyIdentifierData); } catch (IOException e) { LOG.debug("Error parsing authority key identifier structure"); return new TrustLinkerResult(false, TrustLinkerResultReason.INVALID_TRUST, "Error parsing authority key identifier structure"); } String akidId = new String(Hex.encodeHex(authorityKeyIdentifierStructure.getKeyIdentifier())); SubjectKeyIdentifierStructure subjectKeyIdentifierStructure; try { subjectKeyIdentifierStructure = new SubjectKeyIdentifierStructure(subjectKeyIdentifierData); } catch (IOException e) { LOG.debug("Error parsing subject key identifier structure"); return new TrustLinkerResult(false, TrustLinkerResultReason.INVALID_TRUST, "Error parsing subject key identifier structure"); } String skidId = new String(Hex.encodeHex(subjectKeyIdentifierStructure.getKeyIdentifier())); if (!skidId.equals(akidId)) { LOG.debug( "certificate's subject key identifier does not match child certificate's authority key identifier"); return new TrustLinkerResult(false, TrustLinkerResultReason.INVALID_TRUST, "certificate's subject key identifier does not match child certificate's authority key identifier"); } } /* * We don't check pathLenConstraint since this one is only there to * protect the PKI business. */ return null; }