use of org.bouncycastle.cert.jcajce.JcaX509CertificateHolder in project walle by Meituan-Dianping.
the class V1SchemeSigner method generateSignatureBlock.
private static byte[] generateSignatureBlock(SignerConfig signerConfig, byte[] signatureFileBytes) throws InvalidKeyException, CertificateEncodingException, SignatureException {
JcaCertStore certs = new JcaCertStore(signerConfig.certificates);
X509Certificate signerCert = signerConfig.certificates.get(0);
String jcaSignatureAlgorithm = getJcaSignatureAlgorithm(signerCert.getPublicKey(), signerConfig.signatureDigestAlgorithm);
try {
ContentSigner signer = new JcaContentSignerBuilder(jcaSignatureAlgorithm).build(signerConfig.privateKey);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
gen.addSignerInfoGenerator(new SignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build(), SignerInfoSignatureAlgorithmFinder.INSTANCE).setDirectSignature(true).build(signer, new JcaX509CertificateHolder(signerCert)));
gen.addCertificates(certs);
CMSSignedData sigData = gen.generate(new CMSProcessableByteArray(signatureFileBytes), false);
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (ASN1InputStream asn1 = new ASN1InputStream(sigData.getEncoded())) {
DEROutputStream dos = new DEROutputStream(out);
dos.writeObject(asn1.readObject());
}
return out.toByteArray();
} catch (OperatorCreationException | CMSException | IOException e) {
throw new SignatureException("Failed to generate signature", e);
}
}
use of org.bouncycastle.cert.jcajce.JcaX509CertificateHolder in project keycloak by keycloak.
the class OCSPUtils method verifyResponse.
private static void verifyResponse(BasicOCSPResp basicOcspResponse, X509Certificate issuerCertificate, X509Certificate responderCertificate, byte[] requestNonce, Date date) throws NoSuchProviderException, NoSuchAlgorithmException, CertificateNotYetValidException, CertificateExpiredException, CertPathValidatorException {
List<X509CertificateHolder> certs = new ArrayList<>(Arrays.asList(basicOcspResponse.getCerts()));
X509Certificate signingCert = null;
try {
certs.add(new JcaX509CertificateHolder(issuerCertificate));
if (responderCertificate != null) {
certs.add(new JcaX509CertificateHolder(responderCertificate));
}
} catch (CertificateEncodingException e) {
e.printStackTrace();
}
if (certs.size() > 0) {
X500Name responderName = basicOcspResponse.getResponderId().toASN1Primitive().getName();
byte[] responderKey = basicOcspResponse.getResponderId().toASN1Primitive().getKeyHash();
if (responderName != null) {
logger.log(Level.INFO, "Responder Name: {0}", responderName.toString());
for (X509CertificateHolder certHolder : certs) {
try {
X509Certificate tempCert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);
X500Name respName = new X500Name(tempCert.getSubjectX500Principal().getName());
if (responderName.equals(respName)) {
signingCert = tempCert;
logger.log(Level.INFO, "Found a certificate whose principal \"{0}\" matches the responder name \"{1}\"", new Object[] { tempCert.getSubjectDN().getName(), responderName.toString() });
break;
}
} catch (CertificateException e) {
logger.log(Level.FINE, e.getMessage());
}
}
} else if (responderKey != null) {
SubjectKeyIdentifier responderSubjectKey = new SubjectKeyIdentifier(responderKey);
logger.log(Level.INFO, "Responder Key: {0}", Arrays.toString(responderKey));
for (X509CertificateHolder certHolder : certs) {
try {
X509Certificate tempCert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);
SubjectKeyIdentifier subjectKeyIdentifier = null;
if (certHolder.getExtensions() != null) {
subjectKeyIdentifier = SubjectKeyIdentifier.fromExtensions(certHolder.getExtensions());
}
if (subjectKeyIdentifier != null) {
logger.log(Level.INFO, "Certificate: {0}\nSubject Key Id: {1}", new Object[] { tempCert.getSubjectDN().getName(), Arrays.toString(subjectKeyIdentifier.getKeyIdentifier()) });
}
if (subjectKeyIdentifier != null && responderSubjectKey.equals(subjectKeyIdentifier)) {
signingCert = tempCert;
logger.log(Level.INFO, "Found a signer certificate \"{0}\" with the subject key extension value matching the responder key", signingCert.getSubjectDN().getName());
break;
}
subjectKeyIdentifier = new JcaX509ExtensionUtils().createSubjectKeyIdentifier(tempCert.getPublicKey());
if (responderSubjectKey.equals(subjectKeyIdentifier)) {
signingCert = tempCert;
logger.log(Level.INFO, "Found a certificate \"{0}\" with the subject key matching the OCSP responder key", signingCert.getSubjectDN().getName());
break;
}
} catch (CertificateException e) {
logger.log(Level.FINE, e.getMessage());
}
}
}
}
if (signingCert != null) {
if (signingCert.equals(issuerCertificate)) {
logger.log(Level.INFO, "OCSP response is signed by the target''s Issuing CA");
} else if (responderCertificate != null && signingCert.equals(responderCertificate)) {
// https://www.ietf.org/rfc/rfc2560.txt
// 2.6 OCSP Signature Authority Delegation
// - The responder certificate is issued to the responder by CA
logger.log(Level.INFO, "OCSP response is signed by an authorized responder certificate");
} else {
// question."
if (!signingCert.getIssuerX500Principal().equals(issuerCertificate.getSubjectX500Principal())) {
logger.log(Level.INFO, "Signer certificate''s Issuer: {0}\nIssuer certificate''s Subject: {1}", new Object[] { signingCert.getIssuerX500Principal().getName(), issuerCertificate.getSubjectX500Principal().getName() });
throw new CertPathValidatorException("Responder\'s certificate is not authorized to sign OCSP responses");
}
try {
List<String> purposes = signingCert.getExtendedKeyUsage();
if (purposes == null || !purposes.contains(KeyPurposeId.id_kp_OCSPSigning.getId())) {
logger.log(Level.INFO, "OCSPSigning extended usage is not set");
throw new CertPathValidatorException("Responder\'s certificate not valid for signing OCSP responses");
}
} catch (CertificateParsingException e) {
logger.log(Level.FINE, "Failed to get certificate''s extended key usage extension\n{0}", e.getMessage());
}
if (date == null) {
signingCert.checkValidity();
} else {
signingCert.checkValidity(date);
}
try {
Extension noOCSPCheck = new JcaX509CertificateHolder(signingCert).getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck);
// TODO If the extension is present, the OCSP client can trust the
// responder's certificate for the lifetime of the certificate.
logger.log(Level.INFO, "OCSP no-check extension is {0} present", noOCSPCheck == null ? "not" : "");
} catch (CertificateEncodingException e) {
logger.log(Level.FINE, "Certificate encoding exception: {0}", e.getMessage());
}
try {
signingCert.verify(issuerCertificate.getPublicKey());
logger.log(Level.INFO, "OCSP response is signed by an Authorized Responder");
} catch (GeneralSecurityException ex) {
signingCert = null;
}
}
}
if (signingCert == null) {
throw new CertPathValidatorException("Unable to verify OCSP Response\'s signature");
} else {
if (!verifySignature(basicOcspResponse, signingCert)) {
throw new CertPathValidatorException("Error verifying OCSP Response\'s signature");
} else {
Extension responseNonce = basicOcspResponse.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
if (responseNonce != null && requestNonce != null && !Arrays.equals(requestNonce, responseNonce.getExtnValue().getOctets())) {
throw new CertPathValidatorException("Nonces do not match.");
} else {
// See Sun's OCSP implementation.
// https://www.ietf.org/rfc/rfc2560.txt, if nextUpdate is not set,
// the responder is indicating that newer update is avilable all the time
long current = date == null ? System.currentTimeMillis() : date.getTime();
Date stop = new Date(current + (long) TIME_SKEW);
Date start = new Date(current - (long) TIME_SKEW);
Iterator<SingleResp> iter = Arrays.asList(basicOcspResponse.getResponses()).iterator();
SingleResp singleRes = null;
do {
if (!iter.hasNext()) {
return;
}
singleRes = iter.next();
} while (!stop.before(singleRes.getThisUpdate()) && !start.after(singleRes.getNextUpdate() != null ? singleRes.getNextUpdate() : singleRes.getThisUpdate()));
throw new CertPathValidatorException("Response is unreliable: its validity interval is out-of-date");
}
}
}
}
use of org.bouncycastle.cert.jcajce.JcaX509CertificateHolder in project keycloak by keycloak.
the class OCSPUtils method getResponderURIs.
/**
* Extracts OCSP responder URI from X509 AIA v3 extension, if available. There can be
* multiple responder URIs encoded in the certificate.
* @param cert
* @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;
}
Aggregations