List of usage examples for org.bouncycastle.asn1.x509 Extension getExtnValue
public ASN1OctetString getExtnValue()
From source file:org.cesecore.certificates.certificate.certextensions.BasicCertificateExtensionTest.java
License:Open Source License
@Test public void test20CertExtensionEncoding() throws Exception { Properties props = new Properties(); props.put("id1.property.encoding", "DERIA5STRING"); props.put("id1.property.value", "This is a printable string"); BasicCertificateExtension baseExt = new BasicCertificateExtension(); baseExt.init(1, "1.2.3", false, props); byte[] value = baseExt.getValueEncoded(null, null, null, null, null, null); ExtensionsGenerator extgen = new ExtensionsGenerator(); extgen.addExtension(new ASN1ObjectIdentifier(baseExt.getOID()), baseExt.isCriticalFlag(), value); Extensions exts = extgen.generate(); ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(baseExt.getOID()); Extension ext = exts.getExtension(oid); assertNotNull(ext);/*w w w . j av a2 s . c o m*/ // Read the extension value, it's a DERIA5String wrapped in an ASN1OctetString ASN1OctetString str = ext.getExtnValue(); ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(str.getOctets())); DERIA5String ia5str = (DERIA5String) aIn.readObject(); aIn.close(); assertEquals("This is a printable string", ia5str.getString()); }
From source file:org.cesecore.certificates.certificate.CertificateCreateSessionBean.java
License:Open Source License
@Override public CertificateResponseMessage createCertificate(final AuthenticationToken admin, final EndEntityInformation endEntityInformation, final CA ca, final RequestMessage req, final Class<? extends ResponseMessage> responseClass, CertificateGenerationParams certGenParams, final long updateTime) throws CryptoTokenOfflineException, SignRequestSignatureException, IllegalKeyException, IllegalNameException, CustomCertificateSerialNumberException, CertificateCreateException, CertificateRevokeException, CertificateSerialNumberException, AuthorizationDeniedException, IllegalValidityException, CAOfflineException, InvalidAlgorithmException, CertificateExtensionException { if (log.isTraceEnabled()) { log.trace(">createCertificate(IRequestMessage, CA)"); }/*from ww w. j a va 2s. c o m*/ CertificateResponseMessage ret = null; try { final CAToken catoken = ca.getCAToken(); final CryptoToken cryptoToken = cryptoTokenManagementSession.getCryptoToken(catoken.getCryptoTokenId()); final String alias = catoken.getAliasFromPurpose(CATokenConstants.CAKEYPURPOSE_CERTSIGN); // See if we need some key material to decrypt request if (req.requireKeyInfo()) { // You go figure...scep encrypts message with the public CA-cert req.setKeyInfo(ca.getCACertificate(), cryptoToken.getPrivateKey(alias), cryptoToken.getEncProviderName()); } // Verify the request final PublicKey reqpk; try { if (!req.verify()) { throw new SignRequestSignatureException( intres.getLocalizedMessage("createcert.popverificationfailed")); } reqpk = req.getRequestPublicKey(); if (reqpk == null) { final String msg = intres.getLocalizedMessage("createcert.nokeyinrequest"); throw new InvalidKeyException(msg); } } catch (InvalidKeyException e) { // If we get an invalid key exception here, we should throw an IllegalKeyException to the caller // The catch of InvalidKeyException in the end of this method, catches error from the CA crypto token throw new IllegalKeyException(e); } final Date notBefore = req.getRequestValidityNotBefore(); // Optionally requested validity final Date notAfter = req.getRequestValidityNotAfter(); // Optionally requested validity final Extensions exts = req.getRequestExtensions(); // Optionally requested extensions int keyusage = -1; if (exts != null) { if (log.isDebugEnabled()) { log.debug( "we have extensions, see if we can override KeyUsage by looking for a KeyUsage extension in request"); } final Extension ext = exts.getExtension(Extension.keyUsage); if (ext != null) { final ASN1OctetString os = ext.getExtnValue(); DERBitString bs; try { bs = new DERBitString(os.getEncoded()); } catch (IOException e) { throw new IllegalStateException("Unexpected IOException caught."); } keyusage = bs.intValue(); if (log.isDebugEnabled()) { log.debug("We have a key usage request extension: " + keyusage); } } } String sequence = null; byte[] ki = req.getRequestKeyInfo(); // CVC sequence is only 5 characters, don't fill with a lot of garbage here, it must be a readable string if ((ki != null) && (ki.length > 0) && (ki.length < 10)) { final String str = new String(ki); // A cvc sequence must be ascii printable, otherwise it's some binary data if (StringUtils.isAsciiPrintable(str)) { sequence = new String(ki); } } CertificateDataWrapper certWrapper = createCertificate(admin, endEntityInformation, ca, req, reqpk, keyusage, notBefore, notAfter, exts, sequence, certGenParams, updateTime); // Create the response message with all nonces and checks etc ret = ResponseMessageUtils.createResponseMessage(responseClass, req, ca.getCertificateChain(), cryptoToken.getPrivateKey(alias), cryptoToken.getEncProviderName()); ResponseStatus status = ResponseStatus.SUCCESS; FailInfo failInfo = null; String failText = null; if ((certWrapper == null) && (status == ResponseStatus.SUCCESS)) { status = ResponseStatus.FAILURE; failInfo = FailInfo.BAD_REQUEST; } else { ret.setCertificate(certWrapper.getCertificate()); ret.setCACert(ca.getCACertificate()); ret.setBase64CertData(certWrapper.getBase64CertData()); ret.setCertificateData(certWrapper.getCertificateData()); } ret.setStatus(status); if (failInfo != null) { ret.setFailInfo(failInfo); ret.setFailText(failText); } ret.create(); } catch (InvalidKeyException e) { throw new CertificateCreateException(e); } catch (NoSuchAlgorithmException e) { throw new CertificateCreateException(e); } catch (NoSuchProviderException e) { throw new CertificateCreateException(e); } catch (CertificateEncodingException e) { throw new CertificateCreateException(e); } catch (CRLException e) { throw new CertificateCreateException(e); } if (log.isTraceEnabled()) { log.trace("<createCertificate(IRequestMessage, CA)"); } return ret; }
From source file:org.cesecore.certificates.certificate.request.PKCS10RequestMessage.java
License:Open Source License
@Override public String getPassword() { if (password != null) { return password; }/*from w ww . j av a 2 s.c om*/ try { if (pkcs10 == null) { init(); } } catch (NullPointerException e) { log.error("PKCS10 not initated! " + e.getMessage()); return null; } String ret = null; Attribute[] attributes = pkcs10.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_challengePassword); ASN1Encodable obj = null; if (attributes.length == 0) { // See if we have it embedded in an extension request instead attributes = pkcs10.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest); if (attributes.length == 0) { return null; } if (log.isDebugEnabled()) { log.debug("got extension request"); } ASN1Set values = attributes[0].getAttrValues(); if (values.size() == 0) { return null; } Extensions exts = Extensions.getInstance(values.getObjectAt(0)); Extension ext = exts.getExtension(PKCSObjectIdentifiers.pkcs_9_at_challengePassword); if (ext == null) { if (log.isDebugEnabled()) { log.debug("no challenge password extension"); } return null; } obj = ext.getExtnValue(); } else { // If it is a challengePassword directly, it's just to grab the value ASN1Set values = attributes[0].getAttrValues(); obj = values.getObjectAt(0); } if (obj != null) { ASN1String str = null; try { str = DERPrintableString.getInstance((obj)); } catch (IllegalArgumentException ie) { // This was not printable string, should be utf8string then according to pkcs#9 v2.0 str = DERUTF8String.getInstance((obj)); } if (str != null) { ret = str.getString(); } } return ret; }
From source file:org.cesecore.certificates.ocsp.OcspResponseGeneratorSessionBean.java
License:Open Source License
private void assertAcceptableResponseExtension(OCSPReq req) throws OcspFailureException { if (null == req) { throw new IllegalArgumentException(); }// w w w .java 2 s .c om if (req.hasExtensions()) { final Extension acceptableResponsesExtension = req .getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_response); if (acceptableResponsesExtension != null) { // RFC 6960 4.4.3 AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER final ASN1Sequence sequence = ASN1Sequence .getInstance(acceptableResponsesExtension.getExtnValue().getOctets()); @SuppressWarnings("unchecked") final Enumeration<ASN1ObjectIdentifier> oids = sequence.getObjects(); boolean supportsResponseType = false; while (oids.hasMoreElements()) { final ASN1ObjectIdentifier oid = oids.nextElement(); if (oid.equals(OCSPObjectIdentifiers.id_pkix_ocsp_basic)) { // This is the response type we support, so we are happy! Break the loop. supportsResponseType = true; if (log.isDebugEnabled()) { log.debug("Response type supported: " + oid.getId()); } break; } } if (!supportsResponseType) { final String msg = "Required response type not supported, this responder only supports id-pkix-ocsp-basic."; log.info("OCSP Request type not supported: " + msg); throw new OcspFailureException(msg); } } } }
From source file:org.digidoc4j.impl.bdoc.ocsp.BDocTSOcspSourceTest.java
License:GNU General Public License
@Test public void gettingOcspNonce() throws Exception { Configuration configuration = new Configuration(Configuration.Mode.TEST); BDocTSOcspSource ocspSource = new BDocTSOcspSource(configuration); Extension nonce = ocspSource.createNonce(); assertFalse(nonce.isCritical());//from w ww . j a v a 2s .c om assertEquals(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, nonce.getExtnId()); assertTrue(nonce.getExtnValue().toString().length() > 0); }
From source file:org.digidoc4j.impl.bdoc.OcspNonceValidator.java
License:GNU General Public License
private boolean isOcspExtensionValid(Extension extension) { try {//w w w .jav a 2s .co m byte[] octets = extension.getExtnValue().getOctets(); byte[] signatureDigestValue = getSignatureDigestValue(octets); byte[] foundHash = ((DEROctetString) ASN1Sequence.getInstance(octets).getObjectAt(1)).getOctets(); boolean extensionHashMatchesSignatureHash = Arrays.equals(foundHash, signatureDigestValue); logger.debug("OCSP extension contains valid signature digest: " + extensionHashMatchesSignatureHash); return extensionHashMatchesSignatureHash; } catch (Exception e) { logger.error("Invalid nonce format: " + e.getMessage()); return false; } }
From source file:org.ejbca.core.protocol.cmp.RevocationMessageHandler.java
License:Open Source License
public ResponseMessage handleMessage(final BaseCmpMessage msg, boolean authenticated) { if (LOG.isTraceEnabled()) { LOG.trace(">handleMessage"); }/*from ww w. ja v a 2 s. c o m*/ CA ca = null; try { final String caDN = msg.getHeader().getRecipient().getName().toString(); final int caId = CertTools.stringToBCDNString(caDN).hashCode(); if (LOG.isDebugEnabled()) { LOG.debug("CA DN is '" + caDN + "' and resulting caId is " + caId + ", after CertTools.stringToBCDNString conversion."); } ca = caSession.getCA(admin, caId); } catch (CADoesntExistsException e) { final String errMsg = "CA with DN '" + msg.getHeader().getRecipient().getName().toString() + "' is unknown"; LOG.info(errMsg); return CmpMessageHelper.createUnprotectedErrorMessage(msg, ResponseStatus.FAILURE, FailInfo.BAD_REQUEST, errMsg); } catch (AuthorizationDeniedException e) { LOG.info(INTRES.getLocalizedMessage(CMP_ERRORGENERAL, e.getMessage()), e); return CmpMessageHelper.createUnprotectedErrorMessage(msg, ResponseStatus.FAILURE, FailInfo.INCORRECT_DATA, e.getMessage()); } ResponseMessage resp = null; // if version == 1 it is cmp1999 and we should not return a message back // Try to find a HMAC/SHA1 protection key final String keyId = CmpMessageHelper.getStringFromOctets(msg.getHeader().getSenderKID()); ResponseStatus status = ResponseStatus.FAILURE; FailInfo failInfo = FailInfo.BAD_MESSAGE_CHECK; String failText = null; //Verify the authenticity of the message final VerifyPKIMessage messageVerifyer = new VerifyPKIMessage(ca.getCAInfo(), this.confAlias, admin, caSession, endEntityAccessSession, certificateStoreSession, authorizationSession, endEntityProfileSession, authenticationProviderSession, endEntityManagementSession, this.cmpConfiguration); ICMPAuthenticationModule authenticationModule = messageVerifyer .getUsedAuthenticationModule(msg.getMessage(), null, authenticated); if (authenticationModule == null) { LOG.info(messageVerifyer.getErrorMessage()); return CmpMessageHelper.createUnprotectedErrorMessage(msg, ResponseStatus.FAILURE, FailInfo.BAD_MESSAGE_CHECK, messageVerifyer.getErrorMessage()); } // If authentication was correct, we will now try to find the certificate to revoke final PKIMessage pkimsg = msg.getMessage(); final PKIBody body = pkimsg.getBody(); final RevReqContent rr = (RevReqContent) body.getContent(); RevDetails rd; try { rd = rr.toRevDetailsArray()[0]; } catch (Exception e) { LOG.debug("Could not parse the revocation request. Trying to parse it as novosec generated message."); rd = CmpMessageHelper.getNovosecRevDetails(rr); LOG.debug("Succeeded in parsing the novosec generated request."); } final CertTemplate ct = rd.getCertDetails(); final ASN1Integer serno = ct.getSerialNumber(); final X500Name issuer = ct.getIssuer(); // Get the revocation reason. // For CMPv1 this can be a simple DERBitString or it can be a requested CRL Entry Extension // If there exists CRL Entry Extensions we will use that, because it's the only thing allowed in CMPv2 int reason = RevokedCertInfo.REVOCATION_REASON_UNSPECIFIED; final ASN1OctetString reasonoctets = rd.getCrlEntryDetails().getExtension(Extension.reasonCode) .getExtnValue(); DERBitString reasonbits; try { reasonbits = new DERBitString(reasonoctets.getEncoded()); } catch (IOException e1) { LOG.info(INTRES.getLocalizedMessage(CMP_ERRORGENERAL, e1.getMessage()), e1); return CmpMessageHelper.createUnprotectedErrorMessage(msg, ResponseStatus.FAILURE, FailInfo.INCORRECT_DATA, e1.getMessage()); } if (reasonbits != null) { reason = CertTools.bitStringToRevokedCertInfo(reasonbits); if (LOG.isDebugEnabled()) { LOG.debug("CMPv1 revocation reason: " + reason); } } final Extensions crlExt = rd.getCrlEntryDetails(); if (crlExt != null) { final Extension ext = crlExt.getExtension(Extension.reasonCode); if (ext != null) { try { final ASN1InputStream ai = new ASN1InputStream(ext.getExtnValue().getOctets()); final ASN1Primitive obj = ai.readObject(); final ASN1Enumerated crlreason = ASN1Enumerated.getInstance(obj); // RevokedCertInfo.REVOCATION_REASON_AACOMPROMISE are the same integer values as the CRL reason extension code reason = crlreason.getValue().intValue(); if (LOG.isDebugEnabled()) { LOG.debug("CRLReason extension: " + reason); } ai.close(); } catch (IOException e) { LOG.info("Exception parsin CRL reason extension: ", e); } } else { if (LOG.isDebugEnabled()) { LOG.debug("No CRL reason code extension present."); } } } else { if (LOG.isDebugEnabled()) { LOG.debug("No CRL entry extensions present"); } } if ((serno != null) && (issuer != null)) { final String iMsg = INTRES.getLocalizedMessage("cmp.receivedrevreq", issuer.toString(), serno.getValue().toString(16)); LOG.info(iMsg); try { endEntityManagementSession.revokeCert(admin, serno.getValue(), issuer.toString(), reason); status = ResponseStatus.SUCCESS; } catch (AuthorizationDeniedException e) { failInfo = FailInfo.NOT_AUTHORIZED; final String errMsg = INTRES.getLocalizedMessage("cmp.errornotauthrevoke", issuer.toString(), serno.getValue().toString(16)); failText = errMsg; LOG.info(failText); } catch (FinderException e) { failInfo = FailInfo.BAD_CERTIFICATE_ID; final String errMsg = INTRES.getLocalizedMessage("cmp.errorcertnofound", issuer.toString(), serno.getValue().toString(16)); failText = errMsg; // This is already info logged in endEntityManagementSession.revokeCert // LOG.info(failText); } catch (WaitingForApprovalException e) { status = ResponseStatus.GRANTED_WITH_MODS; } catch (ApprovalException e) { failInfo = FailInfo.BAD_REQUEST; final String errMsg = INTRES.getLocalizedMessage("cmp.erroralreadyrequested"); failText = errMsg; LOG.info(failText); } catch (AlreadyRevokedException e) { failInfo = FailInfo.BAD_REQUEST; final String errMsg = INTRES.getLocalizedMessage("cmp.erroralreadyrevoked"); failText = errMsg; // This is already info logged in endEntityManagementSession.revokeCert // LOG.info(failText); } } else { failInfo = FailInfo.BAD_CERTIFICATE_ID; final String errMsg = INTRES.getLocalizedMessage("cmp.errormissingissuerrevoke", issuer.toString(), serno.getValue().toString(16)); failText = errMsg; LOG.info(failText); } if (LOG.isDebugEnabled()) { LOG.debug("Creating a PKI revocation message response"); } final CmpRevokeResponseMessage rresp = new CmpRevokeResponseMessage(); rresp.setRecipientNonce(msg.getSenderNonce()); rresp.setSenderNonce(new String(Base64.encode(CmpMessageHelper.createSenderNonce()))); rresp.setSender(msg.getRecipient()); rresp.setRecipient(msg.getSender()); rresp.setTransactionId(msg.getTransactionId()); rresp.setFailInfo(failInfo); rresp.setFailText(failText); rresp.setStatus(status); if (StringUtils.equals(responseProtection, "pbe")) { final HMACAuthenticationModule hmacmodule = (HMACAuthenticationModule) authenticationModule; final String owfAlg = hmacmodule.getCmpPbeVerifyer().getOwfOid(); final String macAlg = hmacmodule.getCmpPbeVerifyer().getMacOid(); final int iterationCount = 1024; final String cmpRaAuthSecret = hmacmodule.getAuthenticationString(); if ((owfAlg != null) && (macAlg != null) && (keyId != null) && (cmpRaAuthSecret != null)) { // Set all protection parameters if (LOG.isDebugEnabled()) { LOG.debug(responseProtection + ", " + owfAlg + ", " + macAlg + ", " + keyId + ", " + cmpRaAuthSecret); } rresp.setPbeParameters(keyId, cmpRaAuthSecret, owfAlg, macAlg, iterationCount); } } else if (StringUtils.equals(responseProtection, "signature")) { try { final CryptoToken cryptoToken = cryptoTokenSession .getCryptoToken(ca.getCAToken().getCryptoTokenId()); final String aliasCertSign = ca.getCAToken() .getAliasFromPurpose(CATokenConstants.CAKEYPURPOSE_CERTSIGN); rresp.setSignKeyInfo(ca.getCertificateChain(), cryptoToken.getPrivateKey(aliasCertSign), cryptoToken.getSignProviderName()); if (msg.getHeader().getProtectionAlg() != null) { rresp.setPreferredDigestAlg(AlgorithmTools .getDigestFromSigAlg(msg.getHeader().getProtectionAlg().getAlgorithm().getId())); } } catch (CryptoTokenOfflineException e) { LOG.error(e.getLocalizedMessage(), e); } } resp = rresp; try { resp.create(); } catch (InvalidKeyException e) { String errMsg = INTRES.getLocalizedMessage("cmp.errorgeneral"); LOG.error(errMsg, e); } catch (NoSuchAlgorithmException e) { String errMsg = INTRES.getLocalizedMessage("cmp.errorgeneral"); LOG.error(errMsg, e); } catch (NoSuchProviderException e) { String errMsg = INTRES.getLocalizedMessage("cmp.errorgeneral"); LOG.error(errMsg, e); } catch (CertificateEncodingException e) { String errMsg = INTRES.getLocalizedMessage("cmp.errorgeneral"); LOG.error(errMsg, e); } catch (CRLException e) { String errMsg = INTRES.getLocalizedMessage("cmp.errorgeneral"); LOG.error(errMsg, e); } return resp; }
From source file:org.ejbca.core.protocol.ocsp.OCSPUnidClient.java
License:Open Source License
private String getFnr(BasicOCSPResp brep) throws IOException { Extension fnrrep = brep.getExtension(FnrFromUnidExtension.FnrFromUnidOid); if (fnrrep == null) { return null; }//from www . j av a2s. c om ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(fnrrep.getExtnValue().getEncoded())); ASN1OctetString octs = (ASN1OctetString) aIn.readObject(); aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets())); FnrFromUnidExtension fnrobj = FnrFromUnidExtension.getInstance(aIn.readObject()); return fnrobj.getFnr(); }
From source file:org.keycloak.common.util.OCSPUtils.java
License:Apache License
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 {/*from www.j a v a 2 s . c o m*/ 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 { // 4.2.2.2 Authorized Responders // 3. Includes a value of id-ad-ocspSigning in an ExtendedKeyUsage // extension and is issued by the CA that issued the certificate in // 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"); } } } }
From source file:org.keycloak.common.util.OCSPUtils.java
License:Apache License
/** * Extracts OCSP responder URI from X509 AIA v3 extension, if available. There can be * multiple responder URIs encoded in the certificate. * @param cert/*w w w . j a va2 s .c o m*/ * @return a list of available responder URIs. * @throws CertificateEncodingException */ private static List<String> getResponderURIs(X509Certificate cert) throws CertificateEncodingException { LinkedList<String> responderURIs = new LinkedList<>(); JcaX509CertificateHolder holder = new JcaX509CertificateHolder(cert); Extension aia = holder.getExtension(Extension.authorityInfoAccess); if (aia != null) { try { ASN1InputStream in = new ASN1InputStream(aia.getExtnValue().getOctetStream()); ASN1Sequence seq = (ASN1Sequence) in.readObject(); AuthorityInformationAccess authorityInfoAccess = AuthorityInformationAccess.getInstance(seq); for (AccessDescription ad : authorityInfoAccess.getAccessDescriptions()) { if (ad.getAccessMethod().equals(AccessDescription.id_ad_ocsp)) { // See https://www.ietf.org/rfc/rfc2560.txt, 3.1 Certificate Content if (ad.getAccessLocation().getTagNo() == GeneralName.uniformResourceIdentifier) { DERIA5String value = DERIA5String.getInstance(ad.getAccessLocation().getName()); responderURIs.add(value.getString()); } } } } catch (IOException e) { e.printStackTrace(); } } return responderURIs; }