use of org.openecard.bouncycastle.cms.CMSSignedData in project open-ecard by ecsec.
the class SignatureVerifier method validate.
public void validate(@Nonnull byte[] signature) throws KeyStoreException, SignatureInvalid {
try {
// load BC provider, so that the algorithms are available for the signature verification
Security.addProvider(new BouncyCastleProvider());
CMSProcessable wrappedChallenge = new CMSProcessableByteArray(challenge);
CMSSignedData signedData = new CMSSignedData(wrappedChallenge, signature);
Store<X509CertificateHolder> certStore = signedData.getCertificates();
SignerInformationStore signerInfoStore = signedData.getSignerInfos();
Collection<SignerInformation> signers = signerInfoStore.getSigners();
Collection<X509Certificate> allCerts = convertCertificates(certStore.getMatches(new AllSelector()));
for (SignerInformation signer : signers) {
Collection<X509CertificateHolder> certCollection = certStore.getMatches(signer.getSID());
X509CertificateHolder cert = certCollection.iterator().next();
DigestCalculatorProvider dp = new JcaDigestCalculatorProviderBuilder().setProvider("BC").build();
JcaSignerInfoVerifierBuilder verifBuilder = new JcaSignerInfoVerifierBuilder(dp).setProvider("BC");
verifBuilder.setSignatureAlgorithmFinder(new DefaultSignatureAlgorithmIdentifierFinder() {
@Override
public AlgorithmIdentifier find(String sigAlgName) {
if (!AllowedSignatureAlgorithms.isKnownJcaAlgorithm(sigAlgName)) {
throw new IllegalArgumentException("Unsupported signature algorithm used.");
} else {
return super.find(sigAlgName);
}
}
});
SignerInformationVerifier verif = verifBuilder.build(cert);
// verify the signature
if (!signer.verify(verif)) {
throw new SignatureInvalid("Signer information could not be verified.");
}
// verify the path and certificate
X509Certificate x509Cert = convertCertificate(cert);
// TODO: verify that the signature is not too old. How old can it be at max? 1 minute?
validatePath(x509Cert, allCerts, null);
// check that the end certificate is under the admissable certificates
if (ChipGatewayProperties.isUseSubjectWhitelist()) {
X500Principal subj = x509Cert.getSubjectX500Principal();
if (!AllowedSubjects.instance().isInSubjects(subj)) {
String msg = "The certificate used in the signature has an invalid subject: " + subj.getName();
throw new InvalidSubjectException(msg);
}
}
}
// fail if there is no signature in the SignedData structure
if (signers.isEmpty()) {
throw new SignatureInvalid("No signatures present in the given SignedData element.");
}
} catch (CertificateException ex) {
throw new SignatureInvalid("Failed to read a certificate form the CMS data structure.", ex);
} catch (CertPathBuilderException ex) {
throw new SignatureInvalid("Failed to build certificate path for PKIX validation.", ex);
} catch (CMSVerifierCertificateNotValidException ex) {
throw new SignatureInvalid("Signer certificate was not valid when the signature was created.", ex);
} catch (CMSException ex) {
throw new SignatureInvalid("Failed to validate CMS data structure.", ex);
} catch (InvalidSubjectException ex) {
throw new SignatureInvalid("Certificate with invalid subject used in signature.", ex);
} catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | OperatorCreationException ex) {
throw new SignatureInvalid("Invalid or unsupported algorithm or algorithm parameter used in signature.", ex);
} catch (IllegalArgumentException ex) {
throw new SignatureInvalid("Signature containes an invalid value.", ex);
}
}
use of org.openecard.bouncycastle.cms.CMSSignedData in project open-ecard by ecsec.
the class SignatureTest method createSignature.
private CMSSignedData createSignature(String alias, byte[] challenge) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException, InvalidKeyException, SignatureException, OperatorCreationException, CertificateEncodingException, CMSException {
PrivateKey privKey = (PrivateKey) signStore.getKey(alias, pass.toCharArray());
X509Certificate cert = (X509Certificate) signStore.getCertificate(alias);
Certificate[] certChain = (Certificate[]) signStore.getCertificateChain(alias);
Store certs = new JcaCertStore(Arrays.asList(certChain));
// Signature signature = Signature.getInstance("SHA256WithRSA");
// signature.initSign(privKey);
// signature.update(challenge);
// byte[] signedBytes = signature.sign();
CMSTypedData msg = new CMSProcessableByteArray(challenge);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").build(privKey);
DigestCalculatorProvider dgProv = new JcaDigestCalculatorProviderBuilder().build();
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(dgProv).build(signer, cert));
gen.addCertificates(certs);
CMSSignedData sigData = gen.generate(msg, false);
return sigData;
}
use of org.openecard.bouncycastle.cms.CMSSignedData in project open-ecard by ecsec.
the class SignatureTest method testInvalidPath.
@Test
public void testInvalidPath() throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException, InvalidKeyException, SignatureException, OperatorCreationException, CertificateEncodingException, CMSException, IOException, CertificateException, CMSSignerDigestMismatchException, InvalidAlgorithmParameterException {
byte[] challenge = "Hello World!".getBytes(StandardCharsets.UTF_8);
CMSSignedData sigData = createSignature(selfSignedAlias, challenge);
byte[] sigBytes = sigData.getEncoded();
SignatureVerifier validator = new SignatureVerifier(trustStore, challenge);
try {
validator.validate(sigBytes);
Assert.fail("Invalid signature found, expecte a valid one.");
} catch (SignatureInvalid ex) {
}
}
use of org.openecard.bouncycastle.cms.CMSSignedData in project open-ecard by ecsec.
the class SignatureTest method testValidSignature.
@Test
public void testValidSignature() throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException, InvalidKeyException, SignatureException, OperatorCreationException, CertificateEncodingException, CMSException, IOException, CertificateException {
byte[] challenge = "Hello World!".getBytes(StandardCharsets.UTF_8);
CMSSignedData sigData = createSignature(caSignedAlias, challenge);
byte[] sigBytes = sigData.getEncoded();
SignatureVerifier validator = new SignatureVerifier(trustStore, challenge);
try {
validator.validate(sigBytes);
} catch (SignatureInvalid ex) {
Assert.fail("Invalid signature found, expected a valid one.");
}
}
use of org.openecard.bouncycastle.cms.CMSSignedData in project open-ecard by ecsec.
the class SignatureTest method testInvalidSignature.
@Test
public void testInvalidSignature() throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException, InvalidKeyException, SignatureException, OperatorCreationException, CertificateEncodingException, CMSException, IOException, CertificateException {
byte[] challenge = "Hello World!".getBytes(StandardCharsets.UTF_8);
CMSSignedData sigData = createSignature(caSignedAlias, challenge);
byte[] sigBytes = sigData.getEncoded();
// flip a bit in the challenge and see if it still verifies
challenge[0] = 1;
SignatureVerifier validator = new SignatureVerifier(trustStore, challenge);
try {
validator.validate(sigBytes);
Assert.fail("Invalid signature found, expecte a valid one.");
} catch (SignatureInvalid ex) {
}
}
Aggregations