List of usage examples for java.security.cert X509Certificate getPublicKey
public abstract PublicKey getPublicKey();
From source file:org.ejbca.core.protocol.ocsp.OCSPUnidClient.java
private OCSPUnidResponse sendOCSPRequest(byte[] ocspPackage, X509Certificate knownTrustAnchor, boolean useGet) throws IOException, OCSPException, OperatorCreationException, CertificateException, UnrecoverableKeyException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException { final HttpURLConnection con; if (useGet) { String b64 = new String(Base64.encode(ocspPackage, false)); URL url = new URL(httpReqPath + '/' + b64); con = (HttpURLConnection) url.openConnection(); } else {//from ww w. ja va2s . c om // POST the OCSP request URL url = new URL(httpReqPath); con = (HttpURLConnection) getUrlConnection(url); // we are going to do a POST con.setDoOutput(true); con.setRequestMethod("POST"); // POST it con.setRequestProperty("Content-Type", "application/ocsp-request"); OutputStream os = null; try { os = con.getOutputStream(); os.write(ocspPackage); } finally { if (os != null) { os.close(); } } } final OCSPUnidResponse ret = new OCSPUnidResponse(); ret.setHttpReturnCode(con.getResponseCode()); if (ret.getHttpReturnCode() != 200) { if (ret.getHttpReturnCode() == 401) { ret.setErrorCode(OCSPUnidResponse.ERROR_UNAUTHORIZED); } else { ret.setErrorCode(OCSPUnidResponse.ERROR_UNKNOWN); } return ret; } final OCSPResp response; { final InputStream in = con.getInputStream(); if (in != null) { try { response = new OCSPResp(IOUtils.toByteArray(in)); } finally { in.close(); } } else { response = null; } } if (response == null) { ret.setErrorCode(OCSPUnidResponse.ERROR_NO_RESPONSE); return ret; } ret.setResp(response); final BasicOCSPResp brep = (BasicOCSPResp) response.getResponseObject(); if (brep == null) { ret.setErrorCode(OCSPUnidResponse.ERROR_NO_RESPONSE); return ret; } // Compare nonces to see if the server sent the same nonce as we sent final byte[] noncerep = brep.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce).getExtnValue() .getEncoded(); if (noncerep != null) { ASN1InputStream ain = new ASN1InputStream(noncerep); ASN1OctetString oct = ASN1OctetString.getInstance(ain.readObject()); ain.close(); boolean eq = ArrayUtils.isEquals(this.nonce, oct.getOctets()); if (!eq) { ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_NONCE); return ret; } } final RespID id = brep.getResponderId(); final DERTaggedObject to = (DERTaggedObject) id.toASN1Object().toASN1Primitive(); final RespID respId; final X509CertificateHolder[] chain = brep.getCerts(); JcaX509CertificateConverter converter = new JcaX509CertificateConverter(); X509Certificate signerCertificate = converter.getCertificate(chain[0]); final PublicKey signerPub = signerCertificate.getPublicKey(); if (to.getTagNo() == 1) { // This is Name respId = new JcaRespID(signerCertificate.getSubjectX500Principal()); } else { // This is KeyHash respId = new JcaRespID(signerPub, SHA1DigestCalculator.buildSha1Instance()); } if (!id.equals(respId)) { // Response responderId does not match signer certificate responderId! ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERID); } if (!brep.isSignatureValid(new JcaContentVerifierProviderBuilder().build(signerPub))) { ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNATURE); return ret; } /* * Okay, at this point we have three different variables and six different possible valid use cases. These * variables are: * 1. If the OCSP reply is from a CA (integrated) or an OCSP responder (standalone) * 2. If it was from a CA, then if that CA is self signed or a subCA * 3. If the server (in the integrated case) or keybinding (standalone case) was set to include the certificate chain */ //If we have a chain, verify it if (chain.length > 1) { // end at one shortof chain.length, because the root certificate is (usually) not included in the OCSP response // TODO: improve this when we can pass in the root cert from parameter to properly validate the whole chain for (int i = 0; i + 1 < chain.length; i++) { final X509Certificate cert1 = converter.getCertificate(chain[i]); final X509Certificate cert2 = converter.getCertificate(chain[Math.min(i + 1, chain.length - 1)]); try { cert1.verify(cert2.getPublicKey()); } catch (GeneralSecurityException e) { m_log.info("Verifying problem with", e); m_log.info("Certificate to be verified: " + cert1); m_log.info("Verifying certificate: " + cert2); ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERCERT); return ret; } } } if (CertTools.isCA(signerCertificate)) { //Verify that the signer certificate was the same as the trust anchor if (!signerCertificate.getSerialNumber().equals(knownTrustAnchor.getSerialNumber())) { m_log.info("Signing certificate for integrated OCSP was not the provided trust anchor."); ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERCERT); return ret; } } else if (CertTools.isOCSPCert(signerCertificate)) { //If an OCSP certificate was used to sign try { signerCertificate.verify(knownTrustAnchor.getPublicKey()); } catch (GeneralSecurityException e) { m_log.info("Signing certificate was not signed by known trust anchor."); ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERCERT); return ret; } } else { m_log.info("Signing certificate was not an OCSP certificate."); ret.setErrorCode(OCSPUnidResponse.ERROR_INVALID_SIGNERCERT); return ret; } String fnr = getFnr(brep); if (fnr != null) { ret.setFnr(fnr); } return ret; }
From source file:org.ejbca.core.protocol.ocsp.OCSPUtil.java
public static BasicOCSPRespGenerator createOCSPResponse(OCSPReq req, X509Certificate respondercert, int respIdType) throws OCSPException, NotSupportedException { if (null == req) { throw new IllegalArgumentException(); }/*from w ww .j a v a2 s . c o m*/ BasicOCSPRespGenerator res = null; if (respIdType == OcspConfiguration.RESPONDERIDTYPE_NAME) { res = new BasicOCSPRespGenerator(new RespID(respondercert.getSubjectX500Principal())); } else { res = new BasicOCSPRespGenerator(respondercert.getPublicKey()); } X509Extensions reqexts = req.getRequestExtensions(); if (reqexts != null) { X509Extension ext = reqexts.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_response); if (null != ext) { //m_log.debug("Found extension AcceptableResponses"); ASN1OctetString oct = ext.getValue(); try { ASN1Sequence seq = ASN1Sequence.getInstance( new ASN1InputStream(new ByteArrayInputStream(oct.getOctets())).readObject()); Enumeration en = seq.getObjects(); boolean supportsResponseType = false; while (en.hasMoreElements()) { DERObjectIdentifier oid = (DERObjectIdentifier) en.nextElement(); //m_log.debug("Found oid: "+oid.getId()); if (oid.equals(OCSPObjectIdentifiers.id_pkix_ocsp_basic)) { // This is the response type we support, so we are happy! Break the loop. supportsResponseType = true; m_log.debug("Response type supported: " + oid.getId()); continue; } } if (!supportsResponseType) { throw new NotSupportedException( "Required response type not supported, this responder only supports id-pkix-ocsp-basic."); } } catch (IOException e) { } } } return res; }
From source file:org.ejbca.core.protocol.ocsp.OCSPUtil.java
public static BasicOCSPResp generateBasicOCSPResp(OCSPCAServiceRequest serviceReq, String sigAlg, X509Certificate signerCert, PrivateKey signerKey, String provider, X509Certificate[] chain, int respIdType) throws NotSupportedException, OCSPException, NoSuchProviderException, IllegalArgumentException { BasicOCSPResp returnval = null;// ww w . j av a2 s .c om BasicOCSPRespGenerator basicRes = null; basicRes = OCSPUtil.createOCSPResponse(serviceReq.getOCSPrequest(), signerCert, respIdType); ArrayList responses = serviceReq.getResponseList(); if (responses != null) { Iterator iter = responses.iterator(); while (iter.hasNext()) { OCSPResponseItem item = (OCSPResponseItem) iter.next(); basicRes.addResponse(item.getCertID(), item.getCertStatus(), item.getThisUpdate(), item.getNextUpdate(), null); } } X509Extensions exts = serviceReq.getExtensions(); if (exts != null) { Enumeration oids = exts.oids(); if (oids.hasMoreElements()) { basicRes.setResponseExtensions(exts); } } returnval = basicRes.generate(sigAlg, signerKey, chain, new Date(), provider); if (m_log.isDebugEnabled()) { m_log.debug("Signing OCSP response with OCSP signer cert: " + signerCert.getSubjectDN().getName()); RespID respId = null; if (respIdType == OcspConfiguration.RESPONDERIDTYPE_NAME) { respId = new RespID(signerCert.getSubjectX500Principal()); } else { respId = new RespID(signerCert.getPublicKey()); } if (!returnval.getResponderId().equals(respId)) { m_log.error("Response responderId does not match signer certificate responderId!"); } boolean verify = returnval.verify(signerCert.getPublicKey(), "BC"); if (verify) { m_log.debug("The OCSP response is verifying."); } else { m_log.error("The response is NOT verifying!"); } } return returnval; }
From source file:org.ejbca.core.protocol.ocsp.OCSPUtil.java
/** * Method generates an ExtendedCAServiceResponse which is a OCSPCAServiceResponse wrapping the BasicOCSPRespfor usage * internally in EJBCA.// ww w . j a va 2 s . c o m * * @param ocspServiceReq OCSPCAServiceRequest * @param privKey PrivateKey used to sign the OCSP response * @param providerName Provider for the private key, can be on HSM * @param certChain Certificate chain for signing the OCSP response * @return OCSPCAServiceResponse * @throws IllegalExtendedCAServiceRequestException * @throws ExtendedCAServiceRequestException */ public static OCSPCAServiceResponse createOCSPCAServiceResponse(OCSPCAServiceRequest ocspServiceReq, PrivateKey privKey, String providerName, X509Certificate[] certChain) throws IllegalExtendedCAServiceRequestException, ExtendedCAServiceRequestException { final X509Certificate signerCert = certChain[0]; final String sigAlgs = ocspServiceReq.getSigAlg(); final PublicKey pk = signerCert.getPublicKey(); final String sigAlg = OCSPUtil.getSigningAlgFromAlgSelection(sigAlgs, pk); m_log.debug("Signing algorithm: " + sigAlg); final boolean includeChain = ocspServiceReq.includeChain(); m_log.debug("Include chain: " + includeChain); final X509Certificate[] chain; if (includeChain) { chain = certChain; } else { chain = new X509Certificate[1]; chain[0] = signerCert; } try { final int respIdType = ocspServiceReq.getRespIdType(); final BasicOCSPResp ocspresp = OCSPUtil.generateBasicOCSPResp(ocspServiceReq, sigAlg, signerCert, privKey, providerName, chain, respIdType); final OCSPCAServiceResponse result = new OCSPCAServiceResponse(ocspresp, Arrays.asList(chain)); isCertificateValid(signerCert); return result; } catch (OCSPException ocspe) { throw new ExtendedCAServiceRequestException(ocspe); } catch (NoSuchProviderException nspe) { throw new ExtendedCAServiceRequestException(nspe); } catch (NotSupportedException e) { m_log.info("OCSP Request type not supported: ", e); throw new IllegalExtendedCAServiceRequestException(e); } catch (IllegalArgumentException e) { m_log.error("IllegalArgumentException: ", e); throw new IllegalExtendedCAServiceRequestException(e); } }
From source file:org.ejbca.core.protocol.ocsp.OCSPUtil.java
/** Checks the signature on an OCSP request and checks that it is signed by an allowed CA. * Does not check for revocation of the signer certificate * // w w w. ja va 2 s.c om * @param clientRemoteAddr The ip address or hostname of the remote client that sent the request, can be null. * @param req The signed OCSPReq * @param cacerts a CertificateCache of Certificates, the authorized CA-certificates. The signer certificate must be issued by one of these. * @return X509Certificate which is the certificate that signed the OCSP request * @throws SignRequestSignatureException if signature verification fail, or if the signing certificate is not authorized * @throws SignRequestException if there is no signature on the OCSPReq * @throws OCSPException if the request can not be parsed to retrieve certificates * @throws NoSuchProviderException if the BC provider is not installed * @throws CertificateException if the certificate can not be parsed * @throws NoSuchAlgorithmException if the certificate contains an unsupported algorithm * @throws InvalidKeyException if the certificate, or CA key is invalid */ public static X509Certificate checkRequestSignature(String clientRemoteAddr, OCSPReq req, ICertificateCache cacerts) throws SignRequestException, OCSPException, NoSuchProviderException, CertificateException, NoSuchAlgorithmException, InvalidKeyException, SignRequestSignatureException { X509Certificate signercert = null; if (!req.isSigned()) { String infoMsg = intres.getLocalizedMessage("ocsp.errorunsignedreq", clientRemoteAddr); m_log.info(infoMsg); throw new SignRequestException(infoMsg); } // Get all certificates embedded in the request (probably a certificate chain) X509Certificate[] certs = req.getCerts("BC"); // Set, as a try, the signer to be the first certificate, so we have a name to log... String signer = null; if (certs.length > 0) { signer = CertTools.getSubjectDN(certs[0]); } // We must find a cert to verify the signature with... boolean verifyOK = false; for (int i = 0; i < certs.length; i++) { if (req.verify(certs[i].getPublicKey(), "BC") == true) { signercert = certs[i]; signer = CertTools.getSubjectDN(signercert); Date now = new Date(); String signerissuer = CertTools.getIssuerDN(signercert); String infoMsg = intres.getLocalizedMessage("ocsp.infosigner", signer); m_log.info(infoMsg); verifyOK = true; // Also check that the signer certificate can be verified by one of the CA-certificates // that we answer for X509Certificate signerca = cacerts.findLatestBySubjectDN(HashID.getFromIssuerDN(certs[i])); String subject = signer; String issuer = signerissuer; if (signerca != null) { try { signercert.verify(signerca.getPublicKey()); if (m_log.isDebugEnabled()) { m_log.debug("Checking validity. Now: " + now + ", signerNotAfter: " + signercert.getNotAfter()); } CertTools.checkValidity(signercert, now); // Move the error message string to the CA cert subject = CertTools.getSubjectDN(signerca); issuer = CertTools.getIssuerDN(signerca); CertTools.checkValidity(signerca, now); } catch (SignatureException e) { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.invalidcertsignature", subject, issuer, e.getMessage()); m_log.info(infoMsg); verifyOK = false; } catch (InvalidKeyException e) { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.invalidcertsignature", subject, issuer, e.getMessage()); m_log.info(infoMsg); verifyOK = false; } catch (CertificateNotYetValidException e) { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.certnotyetvalid", subject, issuer, e.getMessage()); m_log.info(infoMsg); verifyOK = false; } catch (CertificateExpiredException e) { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.certexpired", subject, issuer, e.getMessage()); m_log.info(infoMsg); verifyOK = false; } } else { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.nocacert", signer, signerissuer); m_log.info(infoMsg); verifyOK = false; } break; } } if (!verifyOK) { String errMsg = intres.getLocalizedMessage("ocsp.errorinvalidsignature", signer); m_log.info(errMsg); throw new SignRequestSignatureException(errMsg); } return signercert; }
From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpStandaloneTest.java
@Test public void testKeyRenewal() throws Exception { //Add localhost to list of rekeying triggering hosts. Set<String> originalHosts = OcspConfiguration.getRekeyingTriggingHosts(); String originalRekeyingPassword = OcspConfiguration.getRekeyingTriggingPassword(); configurationSession.setConfigurationValue(OcspConfiguration.REKEYING_TRIGGERING_HOSTS, "127.0.0.1"); configurationSession.setConfigurationValue(OcspConfiguration.REKEYING_TRIGGERING_PASSWORD, "foo123"); ocspResponseGeneratorTestSession.reloadOcspSigningCache(); List<X509Certificate> oldValues = ocspResponseGeneratorTestSession.getCacheOcspCertificates(); try {/*w w w .java 2 s . c o m*/ X509Certificate cert = getActiveTestCert(); X509Certificate caCertificate = getCaCert(cert); helper.renewAllKeys(); ocspResponseGeneratorTestSession.reloadOcspSigningCache(); List<X509Certificate> newValues = ocspResponseGeneratorTestSession.getCacheOcspCertificates(); //Make sure that cache contains one and only one value assertEquals( "Cache contains a different amount of values after rekeying than before. This indicates a test failure", oldValues.size(), newValues.size()); //Make check that the certificate has changed (sanity check) X509Certificate newSigningCertificate = null; for (X509Certificate signingCertificate : newValues) { if (CertTools.getIssuerDN(signingCertificate).equals(CertTools.getSubjectDN(caCertificate))) { newSigningCertificate = signingCertificate; break; } } assertNotEquals("The same certificate was returned after the renewal process. Key renewal failed", cert.getSerialNumber(), newSigningCertificate.getSerialNumber()); //Make sure that the new certificate is signed by the CA certificate try { newSigningCertificate.verify(caCertificate.getPublicKey()); } catch (SignatureException e) { log.error("Exception caught", e); fail("The new signing certificate was not signed correctly."); } } finally { StringBuilder originalHostsString = new StringBuilder(); for (String host : originalHosts.toArray(new String[originalHosts.size()])) { originalHostsString.append(host + ";"); } configurationSession.setConfigurationValue(OcspConfiguration.REKEYING_TRIGGERING_HOSTS, originalHostsString.toString()); configurationSession.setConfigurationValue(OcspConfiguration.REKEYING_TRIGGERING_PASSWORD, originalRekeyingPassword); } }
From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpTest.java
/** * adds a CA Using ECDSA keys to the database. * * It also checks that the CA is stored correctly. * * @throws Exception/*from ww w .j ava2 s .c o m*/ * error */ private CAInfo addECDSACA(String dn, String keySpec) throws Exception { log.trace(">addECDSACA()"); boolean ret = false; int cryptoTokenId = 0; CAInfo info = null; try { cryptoTokenId = CryptoTokenTestUtils.createCryptoTokenForCA(admin, dn, keySpec); final CAToken catoken = CaTestUtils.createCaToken(cryptoTokenId, AlgorithmConstants.SIGALG_SHA256_WITH_ECDSA, AlgorithmConstants.SIGALG_SHA1_WITH_RSA); // Create and active OSCP CA Service. List<ExtendedCAServiceInfo> extendedcaservices = new ArrayList<ExtendedCAServiceInfo>(); extendedcaservices.add(new HardTokenEncryptCAServiceInfo(ExtendedCAServiceInfo.STATUS_ACTIVE)); extendedcaservices.add(new KeyRecoveryCAServiceInfo(ExtendedCAServiceInfo.STATUS_ACTIVE)); List<CertificatePolicy> policies = new ArrayList<CertificatePolicy>(1); policies.add(new CertificatePolicy("2.5.29.32.0", "", "")); X509CAInfo cainfo = new X509CAInfo(dn, dn, CAConstants.CA_ACTIVE, CertificateProfileConstants.CERTPROFILE_FIXED_ROOTCA, 365, CAInfo.SELFSIGNED, null, catoken); cainfo.setDescription("JUnit ECDSA CA"); cainfo.setPolicies(policies); cainfo.setExtendedCAServiceInfos(extendedcaservices); caAdminSession.createCA(admin, cainfo); info = caSession.getCAInfo(admin, dn); X509Certificate cert = (X509Certificate) info.getCertificateChain().iterator().next(); assertTrue("Error in created ca certificate", cert.getSubjectDN().toString().equals(dn)); assertTrue("Creating CA failed", info.getSubjectDN().equals(dn)); // Make BC cert instead to make sure the public key is BC provider type (to make our test below easier) X509Certificate bccert = (X509Certificate) CertTools.getCertfromByteArray(cert.getEncoded()); PublicKey pk = bccert.getPublicKey(); if (pk instanceof JCEECPublicKey) { JCEECPublicKey ecpk = (JCEECPublicKey) pk; assertEquals(ecpk.getAlgorithm(), "EC"); org.bouncycastle.jce.spec.ECParameterSpec spec = ecpk.getParameters(); if (StringUtils.equals(keySpec, "implicitlyCA")) { assertNull("ImplicitlyCA must have null spec", spec); } else { assertNotNull("secp256r1 must not have null spec", spec); } } else if (pk instanceof BCECPublicKey) { BCECPublicKey ecpk = (BCECPublicKey) pk; assertEquals(ecpk.getAlgorithm(), "EC"); org.bouncycastle.jce.spec.ECParameterSpec spec = ecpk.getParameters(); if (StringUtils.equals(keySpec, "implicitlyCA")) { assertNull("ImplicitlyCA must have null spec", spec); } else { assertNotNull("secp256r1 must not have null spec", spec); } } else { assertTrue("Public key is not EC: " + pk.getClass().getName(), false); } ret = true; } catch (CAExistsException pee) { log.info("CA exists."); } assertTrue("Creating ECDSA CA failed", ret); log.trace("<addECDSACA()"); return info; }
From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpTest.java
/** * adds a CA Using DSA keys to the database. * * It also checks that the CA is stored correctly. * * @throws Exception//from w ww. ja v a 2 s .c om * error */ private X509Certificate addDSACA(String dn, String keySpec) throws Exception { log.trace(">addDSACA()"); boolean ret = false; X509Certificate cacert = null; int cryptoTokenId = 0; try { cryptoTokenId = CryptoTokenTestUtils.createCryptoTokenForCA(admin, dn, keySpec); final CAToken catoken = CaTestUtils.createCaToken(cryptoTokenId, AlgorithmConstants.SIGALG_SHA1_WITH_DSA, AlgorithmConstants.SIGALG_SHA1_WITH_RSA); // Create and active OSCP CA Service. final List<ExtendedCAServiceInfo> extendedcaservices = new ArrayList<ExtendedCAServiceInfo>(); extendedcaservices.add(new HardTokenEncryptCAServiceInfo(ExtendedCAServiceInfo.STATUS_ACTIVE)); extendedcaservices.add(new KeyRecoveryCAServiceInfo(ExtendedCAServiceInfo.STATUS_ACTIVE)); final List<CertificatePolicy> policies = new ArrayList<CertificatePolicy>(1); policies.add(new CertificatePolicy("2.5.29.32.0", "", "")); X509CAInfo cainfo = new X509CAInfo(dn, dn, CAConstants.CA_ACTIVE, CertificateProfileConstants.CERTPROFILE_FIXED_ROOTCA, 365, CAInfo.SELFSIGNED, null, catoken); cainfo.setDescription("JUnit DSA CA"); cainfo.setPolicies(policies); caAdminSession.createCA(admin, cainfo); CAInfo info = caSession.getCAInfo(admin, dn); X509Certificate cert = (X509Certificate) info.getCertificateChain().iterator().next(); assertEquals("Error in created ca certificate", dn, CertTools.getSubjectDN(cert)); assertEquals("Creating CA failed, DN was incorrect.", dn, info.getSubjectDN()); assertTrue("Public key was not an instance of DSAPublicKey", cert.getPublicKey() instanceof DSAPublicKey); ret = true; Collection<Certificate> coll = info.getCertificateChain(); Object[] certs = coll.toArray(); cacert = (X509Certificate) certs[0]; } catch (CAExistsException e) { log.info("CA exists."); throw e; } assertTrue("Creating DSA CA failed", ret); log.trace("<addDSACA()"); return cacert; }
From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpTest.java
/** Checks the signature on an OCSP request and checks that it is signed by an allowed CA. * Does not check for revocation of the signer certificate * /*from w ww .j av a2 s . c o m*/ * @param clientRemoteAddr The ip address or hostname of the remote client that sent the request, can be null. * @param req The signed OCSPReq * @param cacerts a CertificateCache of Certificates, the authorized CA-certificates. The signer certificate must be issued by one of these. * @return X509Certificate which is the certificate that signed the OCSP request * @throws SignRequestSignatureException if signature verification fail, or if the signing certificate is not authorized * @throws SignRequestException if there is no signature on the OCSPReq * @throws OCSPException if the request can not be parsed to retrieve certificates * @throws NoSuchProviderException if the BC provider is not installed * @throws CertificateException if the certificate can not be parsed * @throws NoSuchAlgorithmException if the certificate contains an unsupported algorithm * @throws InvalidKeyException if the certificate, or CA key is invalid * @throws OperatorCreationException */ public static X509Certificate checkRequestSignature(String clientRemoteAddr, OCSPReq req, CaCertificateCache cacerts) throws SignRequestException, OCSPException, NoSuchProviderException, CertificateException, NoSuchAlgorithmException, InvalidKeyException, SignRequestSignatureException, OperatorCreationException { X509Certificate signercert = null; if (!req.isSigned()) { String infoMsg = intres.getLocalizedMessage("ocsp.errorunsignedreq", clientRemoteAddr); log.info(infoMsg); throw new SignRequestException(infoMsg); } // Get all certificates embedded in the request (probably a certificate chain) X509CertificateHolder[] certs = req.getCerts(); // Set, as a try, the signer to be the first certificate, so we have a name to log... String signer = null; JcaX509CertificateConverter converter = new JcaX509CertificateConverter(); if (certs.length > 0) { signer = CertTools.getSubjectDN(converter.getCertificate(certs[0])); } // We must find a cert to verify the signature with... boolean verifyOK = false; for (int i = 0; i < certs.length; i++) { if (req.isSignatureValid(new JcaContentVerifierProviderBuilder().build(certs[i])) == true) { signercert = converter.getCertificate(certs[i]); signer = CertTools.getSubjectDN(signercert); Date now = new Date(); String signerissuer = CertTools.getIssuerDN(signercert); String infoMsg = intres.getLocalizedMessage("ocsp.infosigner", signer); log.info(infoMsg); verifyOK = true; // Also check that the signer certificate can be verified by one of the CA-certificates // that we answer for X509Certificate signerca = cacerts.findLatestBySubjectDN(HashID.getFromIssuerDN(certs[i])); String subject = signer; String issuer = signerissuer; if (signerca != null) { try { signercert.verify(signerca.getPublicKey()); if (log.isDebugEnabled()) { log.debug("Checking validity. Now: " + now + ", signerNotAfter: " + signercert.getNotAfter()); } CertTools.checkValidity(signercert, now); // Move the error message string to the CA cert subject = CertTools.getSubjectDN(signerca); issuer = CertTools.getIssuerDN(signerca); CertTools.checkValidity(signerca, now); } catch (SignatureException e) { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.invalidcertsignature", subject, issuer, e.getMessage()); log.info(infoMsg); verifyOK = false; } catch (InvalidKeyException e) { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.invalidcertsignature", subject, issuer, e.getMessage()); log.info(infoMsg); verifyOK = false; } catch (CertificateNotYetValidException e) { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.certnotyetvalid", subject, issuer, e.getMessage()); log.info(infoMsg); verifyOK = false; } catch (CertificateExpiredException e) { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.certexpired", subject, issuer, e.getMessage()); log.info(infoMsg); verifyOK = false; } } else { infoMsg = intres.getLocalizedMessage("ocsp.infosigner.nocacert", signer, signerissuer); log.info(infoMsg); verifyOK = false; } break; } } if (!verifyOK) { String errMsg = intres.getLocalizedMessage("ocsp.errorinvalidsignature", signer); log.info(errMsg); throw new SignRequestSignatureException(errMsg); } return signercert; }
From source file:org.ejbca.core.protocol.scep.ProtocolScepHttpTest.java
private void checkScepResponse(byte[] retMsg, String userDN, String _senderNonce, String _transId, boolean crlRep, String digestOid, boolean noca) throws CMSException, OperatorCreationException, NoSuchProviderException, CRLException, InvalidKeyException, NoSuchAlgorithmException, SignatureException, CertificateException { // Parse response message ////from w w w.j ava2 s . c o m CMSSignedData s = new CMSSignedData(retMsg); // The signer, i.e. the CA, check it's the right CA SignerInformationStore signers = s.getSignerInfos(); @SuppressWarnings("unchecked") Collection<SignerInformation> col = signers.getSigners(); assertTrue(col.size() > 0); Iterator<SignerInformation> iter = col.iterator(); SignerInformation signerInfo = iter.next(); // Check that the message is signed with the correct digest alg assertEquals(signerInfo.getDigestAlgOID(), digestOid); SignerId sinfo = signerInfo.getSID(); // Check that the signer is the expected CA assertEquals(CertTools.stringToBCDNString(cacert.getIssuerDN().getName()), CertTools.stringToBCDNString(sinfo.getIssuer().toString())); // Verify the signature JcaDigestCalculatorProviderBuilder calculatorProviderBuilder = new JcaDigestCalculatorProviderBuilder() .setProvider(BouncyCastleProvider.PROVIDER_NAME); JcaSignerInfoVerifierBuilder jcaSignerInfoVerifierBuilder = new JcaSignerInfoVerifierBuilder( calculatorProviderBuilder.build()).setProvider(BouncyCastleProvider.PROVIDER_NAME); boolean ret = signerInfo.verify(jcaSignerInfoVerifierBuilder.build(cacert.getPublicKey())); assertTrue(ret); // Get authenticated attributes AttributeTable tab = signerInfo.getSignedAttributes(); // --Fail info Attribute attr = tab.get(new ASN1ObjectIdentifier(ScepRequestMessage.id_failInfo)); // No failInfo on this success message assertNull(attr); // --Message type attr = tab.get(new ASN1ObjectIdentifier(ScepRequestMessage.id_messageType)); assertNotNull(attr); ASN1Set values = attr.getAttrValues(); assertEquals(values.size(), 1); ASN1String str = DERPrintableString.getInstance((values.getObjectAt(0))); String messageType = str.getString(); assertEquals("3", messageType); // --Success status attr = tab.get(new ASN1ObjectIdentifier(ScepRequestMessage.id_pkiStatus)); assertNotNull(attr); values = attr.getAttrValues(); assertEquals(values.size(), 1); str = DERPrintableString.getInstance((values.getObjectAt(0))); assertEquals(ResponseStatus.SUCCESS.getStringValue(), str.getString()); // --SenderNonce attr = tab.get(new ASN1ObjectIdentifier(ScepRequestMessage.id_senderNonce)); assertNotNull(attr); values = attr.getAttrValues(); assertEquals(values.size(), 1); ASN1OctetString octstr = ASN1OctetString.getInstance(values.getObjectAt(0)); // SenderNonce is something the server came up with, but it should be 16 // chars assertTrue(octstr.getOctets().length == 16); // --Recipient Nonce attr = tab.get(new ASN1ObjectIdentifier(ScepRequestMessage.id_recipientNonce)); assertNotNull(attr); values = attr.getAttrValues(); assertEquals(values.size(), 1); octstr = ASN1OctetString.getInstance(values.getObjectAt(0)); // recipient nonce should be the same as we sent away as sender nonce assertEquals(_senderNonce, new String(Base64.encode(octstr.getOctets()))); // --Transaction ID attr = tab.get(new ASN1ObjectIdentifier(ScepRequestMessage.id_transId)); assertNotNull(attr); values = attr.getAttrValues(); assertEquals(values.size(), 1); str = DERPrintableString.getInstance((values.getObjectAt(0))); // transid should be the same as the one we sent assertEquals(_transId, str.getString()); // // Check different message types // if (messageType.equals("3")) { // First we extract the encrypted data from the CMS enveloped data // contained // within the CMS signed data final CMSProcessable sp = s.getSignedContent(); final byte[] content = (byte[]) sp.getContent(); final CMSEnvelopedData ed = new CMSEnvelopedData(content); final RecipientInformationStore recipients = ed.getRecipientInfos(); Store certstore; @SuppressWarnings("unchecked") Collection<RecipientInformation> c = recipients.getRecipients(); assertEquals(c.size(), 1); Iterator<RecipientInformation> riIterator = c.iterator(); byte[] decBytes = null; RecipientInformation recipient = riIterator.next(); JceKeyTransEnvelopedRecipient rec = new JceKeyTransEnvelopedRecipient(key1.getPrivate()); rec.setContentProvider(BouncyCastleProvider.PROVIDER_NAME); decBytes = recipient.getContent(rec); // This is yet another CMS signed data CMSSignedData sd = new CMSSignedData(decBytes); // Get certificates from the signed data certstore = sd.getCertificates(); if (crlRep) { // We got a reply with a requested CRL @SuppressWarnings("unchecked") final Collection<X509CRLHolder> crls = (Collection<X509CRLHolder>) sd.getCRLs().getMatches(null); assertEquals(crls.size(), 1); final Iterator<X509CRLHolder> it = crls.iterator(); // CRL is first (and only) final X509CRL retCrl = new JcaX509CRLConverter().getCRL(it.next()); log.info("Got CRL with DN: " + retCrl.getIssuerDN().getName()); // check the returned CRL assertEquals(CertTools.getSubjectDN(cacert), CertTools.getIssuerDN(retCrl)); retCrl.verify(cacert.getPublicKey()); } else { // We got a reply with a requested certificate @SuppressWarnings("unchecked") final Collection<X509CertificateHolder> certs = (Collection<X509CertificateHolder>) certstore .getMatches(null); // EJBCA returns the issued cert and the CA cert (cisco vpn // client requires that the ca cert is included) if (noca) { assertEquals(certs.size(), 1); } else { assertEquals(certs.size(), 2); } final Iterator<X509CertificateHolder> it = certs.iterator(); // Issued certificate must be first boolean verified = false; boolean gotcacert = false; JcaX509CertificateConverter jcaX509CertificateConverter = new JcaX509CertificateConverter(); while (it.hasNext()) { X509Certificate retcert = jcaX509CertificateConverter.getCertificate(it.next()); log.info("Got cert with DN: " + retcert.getSubjectDN().getName()); // check the returned certificate String subjectdn = CertTools.stringToBCDNString(retcert.getSubjectDN().getName()); if (CertTools.stringToBCDNString(userDN).equals(subjectdn)) { // issued certificate assertEquals(CertTools.stringToBCDNString(userDN), subjectdn); assertEquals(CertTools.getSubjectDN(cacert), CertTools.getIssuerDN(retcert)); retcert.verify(cacert.getPublicKey()); assertTrue(checkKeys(key1.getPrivate(), retcert.getPublicKey())); verified = true; } else { // ca certificate assertEquals(CertTools.getSubjectDN(cacert), CertTools.getSubjectDN(retcert)); gotcacert = true; } } assertTrue(verified); if (noca) { assertFalse(gotcacert); } else { assertTrue(gotcacert); } } } }