/** * Validates that a signed entity has a valid message and signature. The signer's certificate is * validated to ensure authenticity of the message. Message tampering is also checked with the * message's digest and the signed digest in the message signature. * * @param signedEntity The entity containing the original signed part and the message signature. * @param signerCertificate The certificate used to sign the message. * @param anchors A collection of certificate anchors used to determine if the certificates used * in the signature can be validated as trusted certificates. */ public void checkSignature( SignedEntity signedEntity, X509Certificate signerCertificate, Collection<X509Certificate> anchors) throws SignatureValidationException { CMSSignedData signatureEnvelope = deserializeSignatureEnvelope(signedEntity); try { // there may be multiple signatures in the signed part... iterate through all the signing // certificates until one // is verified with the signerCertificate for (SignerInformation sigInfo : (Collection<SignerInformation>) signatureEnvelope.getSignerInfos().getSigners()) if (sigInfo.verify(signerCertificate, CryptoExtensions.getJCEProviderName())) return; // verified... return // at this point the signerCertificate cannot be verified with one of the signing // certificates.... throw new SignatureValidationException("Signature validation failure."); } catch (SignatureValidationException sve) { throw sve; } catch (Exception e) { throw new SignatureValidationException("Signature validation failure.", e); } }
private int verify(String signatureb64) { int verified = 0; try { CMSSignedData signature = new CMSSignedData(Base64.decode(signatureb64)); // batch verification Store certs = signature.getCertificates(); SignerInformationStore signers = signature.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation) it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next(); System.out.println(verified); if (signer.verify( new JcaSimpleSignerInfoVerifierBuilder() .setProvider(new BouncyCastleProvider()) .build(certHolder))) { verified++; } } System.out.println(verified); } catch (CMSException | StoreException | CertificateException | OperatorCreationException ex) { System.err.println("error : " + ex.getMessage()); } return verified; }
@Test public void testCMD() throws Exception { Authentication auth = new SkeletonKeyClientBuilder() .username("wburke") .password("geheim") .authentication("Skeleton Key"); ResteasyClient client = new ResteasyClient(); WebTarget target = client.target(generateBaseUrl()); String tiny = target.path("tokens").path("url").request().post(Entity.json(auth), String.class); System.out.println(tiny); System.out.println("tiny.size: " + tiny.length()); Security.addProvider(new BouncyCastleProvider()); KeyPair keyPair = KeyPairGenerator.getInstance("RSA", "BC").generateKeyPair(); PrivateKey privateKey = keyPair.getPrivate(); X509Certificate cert = KeyTools.generateTestCertificate(keyPair); byte[] signed = p7s(privateKey, cert, null, tiny.getBytes()); CMSSignedData data = new CMSSignedData(signed); byte[] bytes = (byte[]) data.getSignedContent().getContent(); System.out.println("BYTES: " + new String(bytes)); System.out.println("size:" + signed.length); System.out.println("Base64.size: " + Base64.encodeBytes(signed).length()); SignerInformation signer = (SignerInformation) data.getSignerInfos().getSigners().iterator().next(); System.out.println("valid: " + signer.verify(cert, "BC")); }
private void verifyRSASignatures(CMSSignedData s, byte[] contentDigest) throws Exception { Store certStore = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation) it.next(); Collection certCollection = certStore.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder) certIt.next(); if (!signer.verify( new BcRSASignerInfoVerifierBuilder( new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), new DefaultDigestAlgorithmIdentifierFinder(), new BcDigestCalculatorProvider()) .build(cert))) { fail("signature verification failed"); } if (contentDigest != null) { if (!Arrays.areEqual(contentDigest, signer.getContentDigest())) { fail("digest verification failed"); } } } }
/** * Verify the email is signed by the given certificate. * * @param signedData * @param mailMsg * @return * @throws CMSException * @throws OperatorCreationException * @throws CertificateException */ @SuppressWarnings({"rawtypes"}) protected boolean isValid(CMSSignedData signedData, MailMessage mailMsg) throws OperatorCreationException, CMSException, CertificateException { boolean verify = false; SignerInformationStore signerStore = signedData.getSignerInfos(); Iterator<SignerInformation> it = signerStore.getSigners().iterator(); while (it.hasNext()) { SignerInformation signer = it.next(); org.bouncycastle.util.Store store = signedData.getCertificates(); @SuppressWarnings("unchecked") Collection certCollection = store.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next(); X509Certificate certificate = new JcaX509CertificateConverter().setProvider(PROVIDER_NAME).getCertificate(certHolder); verify = signer.verify( new JcaSimpleSignerInfoVerifierBuilder() .setProvider(PROVIDER_NAME) .build(certificate)); mailMsg.setHasSignature(true); mailMsg.setSignaturePassed(verify); mailMsg.setNameOfPrincipal(certificate.getSubjectDN().getName()); } return verify; }
public void appendSignatureTimeStamp(byte[] timeStampTokenBytes) { try { AttributeTable at = firstSignerInfo.getUnsignedAttributes(); firstSignerInfo = SignerInformation.replaceUnsignedAttributes( firstSignerInfo, appendTimestampAttribute(timeStampTokenBytes, at)); Collection<SignerInformation> signers = new ArrayList<SignerInformation>(1); signers.add(firstSignerInfo); SignerInformationStore sis = new SignerInformationStore(signers); cmsSignedData = CMSSignedData.replaceSigners(cmsSignedData, sis); } catch (Exception e) { ExceptionHandlerTyped.<SPISignatureException>handle(SPISignatureException.class, e); } }
// controlla che nel firmatario sia presente l'attributo ESSCertIDv2 e che esso sia valido // in questo caso la busta crittografica è espressa correttamente nel formato CADES-BES secondo // la DELIBERAZIONE ministeriale del N . 45 DEL 21 MAGGIO 2009 private boolean isLegallySigned(SignerInformation signer, X509CertificateHolder cert) throws FirmapiuException, NoSuchAlgorithmException, IOException { AttributeTable signAttr = signer.getSignedAttributes(); if (signAttr == null) throw new FirmapiuException(VERIFY_SIGNER_SIGNINGATTRIBUTE_NOTFOUND); Attribute attr = signAttr.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2); if (attr == null) throw new FirmapiuException(VERIFY_SIGNER_SIGNINGATTRIBUTE_NOTFOUND); ASN1Sequence sequence = ASN1Sequence.getInstance(attr.getAttrValues().getObjectAt(0)); SigningCertificateV2 scv2 = SigningCertificateV2.getInstance(sequence); ESSCertIDv2[] essCert = scv2.getCerts(); if (essCert == null || essCert.length < 1) throw new FirmapiuException(VERIFY_SIGNER_SIGNINGATTRIBUTE_NOTFOUND); // controlla l'hash del certificato se si restituisce true se no restituisce no // aggiungere hash del certificato di sottoscrizione String digestAlgorithm = "SHA-256"; MessageDigest sha = null; sha = MessageDigest.getInstance(digestAlgorithm); byte[] digestedCert = sha.digest(cert.getEncoded()); byte[] essCertHash = essCert[0].getCertHash(); // affinché la firma sia valida digestCert e essCertHash devono essere uguali if (digestedCert.length != essCertHash.length) return false; else { for (int i = 0; i < digestedCert.length; i++) if (digestedCert[i] != essCertHash[i]) { return false; } return true; } // fine if } // fine metodo
// recupera il signing time di un firmatario private static Date getSigningTime(SignerInformation signer) throws FirmapiuException { AttributeTable signedAttr = signer.getSignedAttributes(); Attribute signingTimeAttr = signedAttr.get(CMSAttributes.signingTime); if (signingTimeAttr != null) { Enumeration<?> en = signingTimeAttr.getAttrValues().getObjects(); Date signingTime = null; Object obj = en.nextElement(); try { if (obj instanceof ASN1UTCTime) { ASN1UTCTime asn1Time = (ASN1UTCTime) obj; signingTime = asn1Time.getDate(); } else if (obj instanceof DERUTCTime) { DERUTCTime derTime = (DERUTCTime) obj; signingTime = derTime.getDate(); } return signingTime; } catch (ParseException e) { // TODO eccezioni ammodo throw new FirmapiuException(); } } else { // non ha trovato il signing time come attributo // TODO eccezioni ammodo throw new FirmapiuException(); } } // fine metodo
/** * Return a signer information object with passed in SignerInformationStore representing counter * signatures attached as an unsigned attribute. * * @param signerInformation the signerInfo to be used as the basis. * @param counterSigners signer info objects carrying counter signature. * @return a copy of the original SignerInformationObject with the changed attributes. */ public static SignerInformation addCounterSigners( SignerInformation signerInformation, SignerInformationStore counterSigners) { // TODO Perform checks from RFC 3852 11.4 SignerInfo sInfo = signerInformation.info; AttributeTable unsignedAttr = signerInformation.getUnsignedAttributes(); ASN1EncodableVector v; if (unsignedAttr != null) { v = unsignedAttr.toASN1EncodableVector(); } else { v = new ASN1EncodableVector(); } ASN1EncodableVector sigs = new ASN1EncodableVector(); for (Iterator it = counterSigners.getSigners().iterator(); it.hasNext(); ) { sigs.add(((SignerInformation) it.next()).toSignerInfo()); } v.add(new Attribute(CMSAttributes.counterSignature, new DERSet(sigs))); return new SignerInformation( new SignerInfo( sInfo.getSID(), sInfo.getDigestAlgorithm(), sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), new DERSet(v)), signerInformation.contentType, signerInformation.content, null, new DefaultSignatureAlgorithmIdentifierFinder()); }
private void verifySigners(Store certs, SignerInformationStore signers) throws Exception { Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation) it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next(); assertEquals( true, signer.verify( new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(certHolder))); } }
public TimestampToken getContentTimestamp() { try { return SignedAttributesHelper.getContentTimestamp(firstSignerInfo.getSignedAttributes()); } catch (Exception e) { ExceptionHandlerTyped.<SPISignatureException>handle(SPISignatureException.class, e); } return null; }
// OCSP responses found as signed ID_ADBE_REVOCATION attribute public Set<OCSPResponse> getSignedOCSPResponses() { try { AttributeTable table = firstSignerInfo.getSignedAttributes(); return SignedAttributesHelper.getSignedOCSPResponses(table); } catch (Exception e) { ExceptionHandlerTyped.<SPISignatureException>handle(SPISignatureException.class, e); } return null; }
// CRLS found as signed ID_ADBE_REVOCATION attribute public Collection<CRL> getSignedCRLs() { try { AttributeTable table = firstSignerInfo.getSignedAttributes(); return SignedAttributesHelper.getSignedCRLs(table); } catch (Exception e) { ExceptionHandlerTyped.<SPISignatureException>handle(SPISignatureException.class, e); } return null; }
/** * Tests that it is possible to specify a signature algorithm who's name is not simply a * concatenation of a digest algorithm and the key algorithm. * * <p>This test also sets the signature provider as a provider supporting the RSASSA-PSS * algorithms might not be installed. * * @throws Exception */ public void testWithSignatureAlgorithmSHA256withRSAandMGF1() throws Exception { File sourceFile = new File("target/test-classes/wineyes.exe"); File targetFile = new File("target/test-classes/wineyes-signed.exe"); FileUtils.copyFile(sourceFile, targetFile); PEFile peFile = null; try { peFile = new PEFile(targetFile); PESigner signer = new PESigner(getKeyStore(), ALIAS, PRIVATE_KEY_PASSWORD) .withTimestamping(false) .withDigestAlgorithm(DigestAlgorithm.SHA1) .withSignatureAlgorithm("SHA256withRSAandMGF1", new BouncyCastleProvider()); signer.sign(peFile); peFile = new PEFile(targetFile); List<CMSSignedData> signatures = peFile.getSignatures(); assertNotNull(signatures); assertEquals(1, signatures.size()); CMSSignedData signedData = signatures.get(0); assertNotNull(signedData); // Check the signature algorithm final SignerInformation si = (SignerInformation) signedData.getSignerInfos().getSigners().iterator().next(); assertEquals( "Digest algorithm", NISTObjectIdentifiers.id_sha256, si.getDigestAlgorithmID().getAlgorithm()); assertEquals( "Encryption algorithm", PKCSObjectIdentifiers.id_RSASSA_PSS.getId(), si.getEncryptionAlgOID()); } finally { if (peFile != null) { peFile.close(); } } }
public static boolean isValidSignature(CMSSignedData signedData, X509Certificate rootCert) throws Exception { boolean[] bArr = new boolean[2]; bArr[0] = true; CertStore certsAndCRLs = signedData.getCertificatesAndCRLs("Collection", "BC"); SignerInformationStore signers = signedData.getSignerInfos(); Iterator it = signers.getSigners().iterator(); if (it.hasNext()) { SignerInformation signer = (SignerInformation) it.next(); SignerId signerConstraints = signer.getSID(); signerConstraints.setKeyUsage(bArr); PKIXCertPathBuilderResult result = buildPath(rootCert, signer.getSID(), certsAndCRLs); return signer.verify(result.getPublicKey(), "BC"); } return false; }
/** verify the signature (assuming the cert is contained in the message) */ private static void verify(SMIMESigned s) throws Exception { // // extract the information to verify the signatures. // // // certificates and crls passed in the signature // Store certs = s.getCertificates(); // // SignerInfo blocks which contain the signatures // SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); // // check each signer // while (it.hasNext()) { SignerInformation signer = (SignerInformation) it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509Certificate cert = new JcaX509CertificateConverter() .setProvider(BC) .getCertificate((X509CertificateHolder) certIt.next()); // // verify that the sig is correct and that it was generated // when the certificate was current // if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))) { System.out.println("signature verified"); } else { System.out.println("signature failed!"); } } }
public boolean verifyEstrai(String pathBase, File pathFilesSignedd) { boolean esito = false; byte[] buffer = new byte[(int) pathFilesSignedd.length()]; DataInputStream in; try { in = new DataInputStream(new FileInputStream(pathFilesSignedd)); in.readFully(buffer); in.close(); Security.addProvider(new BouncyCastleProvider()); CMSSignedData signature = new CMSSignedData(buffer); SignerInformation signer = (SignerInformation) signature.getSignerInfos().getSigners().iterator().next(); CertStore cs = signature.getCertificatesAndCRLs("Collection", "BC"); Iterator iter = cs.getCertificates(signer.getSID()).iterator(); X509Certificate certificate = (X509Certificate) iter.next(); CMSProcessable sc = signature.getSignedContent(); byte[] data = (byte[]) sc.getContent(); // Verifie la signature // System.out.println(signer.verify(certificate, "BC")); esito = signer.verify(certificate.getPublicKey(), "BC"); System.out.println("Verifica FILE: " + esito); String fatturapaName = pathFilesSignedd.getName().substring(0, pathFilesSignedd.getName().length() - 4).trim(); System.out.println(" test:" + fatturapaName); FileOutputStream envfos = new FileOutputStream(new File(pathBase, fatturapaName)); envfos.write(data); envfos.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return esito; }
public List<TimestampToken> getSignatureTimestamps() { if (signatureTimeStamps == null) { try { signatureTimeStamps = UnsignedAttributesHelper.getSignatureTimestamps( firstSignerInfo.getUnsignedAttributes()); } catch (Exception e) { ExceptionHandlerTyped.<SPISignatureException>handle(SPISignatureException.class, e); } } return signatureTimeStamps; }
public Certificate getSignerCertificate() { try { Collection certificateCollection = cmsSignedData.getCertificates().getMatches(firstSignerInfo.getSID()); Iterator iterator = certificateCollection.iterator(); X509CertificateHolder certHolder = (X509CertificateHolder) iterator.next(); return CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME) .generateCertificate(new ByteArrayInputStream(certHolder.getEncoded())); } catch (Exception e) { log.error(Channel.TECH, "Could not extract signer certificate from CMS signature : %1$s", e); } return null; }
public void testDoubleNlCanonical() throws Exception { MimeMessage message = loadMessage("3nnn_smime.eml"); SMIMESigned s = new SMIMESigned((MimeMultipart) message.getContent()); Collection c = s.getSignerInfos().getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation) it.next(); Collection certCollection = s.getCertificates().getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next(); // in this case the sig is invalid, but it's the lack of an exception from the content digest // we're looking for Assert.assertFalse( signer.verify( new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(certHolder))); } }
/** * @param signerInformation {@code SignerInformation} * @return {@code DERTaggedObject} representing the signed attributes * @throws DSSException in case of a decoding problem */ public static DERTaggedObject getSignedAttributes(final SignerInformation signerInformation) throws DSSException { try { final byte[] encodedSignedAttributes = signerInformation.getEncodedSignedAttributes(); if (encodedSignedAttributes == null) { return null; } final ASN1Set asn1Set = DSSASN1Utils.toASN1Primitive(encodedSignedAttributes); return new DERTaggedObject(false, 0, asn1Set); } catch (IOException e) { throw new DSSException(e); } }
private Date findTimestamp(CMSSignedData cmsSignedData) { Iterator iterator = cmsSignedData.getSignerInfos().getSigners().iterator(); while (iterator.hasNext()) { SignerInformation signerInformation = (SignerInformation) iterator.next(); AttributeTable signedAttrTable = signerInformation.getSignedAttributes(); if (signedAttrTable == null) { continue; } ASN1EncodableVector v = signedAttrTable.getAll(CMSAttributes.signingTime); switch (v.size()) { case 0: continue; case 1: Attribute t = (Attribute) v.get(0); ASN1Set attrValues = t.getAttrValues(); if (attrValues.size() != 1) { continue; } // found it try { return ((ASN1UTCTime) attrValues.getObjectAt(0).getDERObject()).getDate(); } catch (ParseException e) { e.printStackTrace(); } continue; default: continue; } } // no timestamp found return null; }
public boolean doJob() { String strMethod = "doJob()"; try { // _validateCmsSignature(); CMSSignedData cms = _getSignPkcs7(); SignerInformationStore sis = cms.getSignerInfos(); Collection colSignerInfo = sis.getSigners(); Iterator itrSignerInfo = colSignerInfo.iterator(); SignerInformation sin = (SignerInformation) itrSignerInfo.next(); // r�cup�ration du certificat du signataire CertStore cse = cms.getCertificatesAndCRLs("Collection", CmsVerif._STR_KST_PROVIDER_BC); Iterator itrCert = cse.getCertificates(sin.getSID()).iterator(); X509Certificate crt = (X509Certificate) itrCert.next(); // Verifie la signature boolean blnCoreValidity = sin.verify(crt, CmsVerif._STR_KST_PROVIDER_BC); if (blnCoreValidity) { MySystem.s_printOutTrace(this, strMethod, "blnCoreValidity=true"); String strBody = "CMS Detached signature is OK!"; strBody += "\n\n" + ". CMS signature file location:"; strBody += "\n " + super._strPathAbsFileSig_; strBody += "\n\n" + ". Data file location:"; strBody += "\n " + super._strPathAbsFileData_; OPAbstract.s_showDialogInfo(super._frmOwner_, strBody); // SignerInfo sio = sin.toSignerInfo(); SignerId sid = sin.getSID(); if (sid != null) { System.out.println("sid.getSerialNumber()=" + sid.getSerialNumber()); System.out.println("sid.getIssuerAsString()=" + sid.getIssuerAsString()); System.out.println("sid.getSubjectAsString()=" + sid.getSubjectAsString()); } /*System.out.println("sin.getDigestAlgOID()=" + sin.getDigestAlgOID()); System.out.println("sin.getEncryptionAlgOID()=" + sin.getEncryptionAlgOID()); System.out.println("sin.toString()=" + sin.toString()); System.out.println("sin.getVersion()=" + sin.getVersion());*/ } else { MySystem.s_printOutWarning(this, strMethod, "blnCoreValidity=true"); String strBody = "CMS Detached signature is WRONG!"; strBody += "\n\n" + ". CMS signature file location:"; strBody += "\n " + super._strPathAbsFileSig_; strBody += "\n\n" + ". Data file location:"; strBody += "\n " + super._strPathAbsFileData_; OPAbstract.s_showDialogWarning(super._frmOwner_, strBody); } } catch (Exception exc) { exc.printStackTrace(); MySystem.s_printOutError(this, strMethod, "exc caught"); String strBody = "Failed to verify CMS detached signature."; strBody += "\n\n" + "Possible reason: wrong data file"; strBody += "\n\n" + "got exception."; strBody += "\n" + exc.getMessage(); strBody += "\n\n" + "More: see your session.log"; OPAbstract.s_showDialogError(super._frmOwner_, strBody); return false; } // TODO return true; }
public SignerLocation getSignerLocationAttribute() { return SignedAttributesHelper.getSignerLocationAttribute(firstSignerInfo.getSignedAttributes()); }
public SignerAttribute getSignerAttributesAttribute() { return SignedAttributesHelper.getSignerAttributesAttribute( firstSignerInfo.getSignedAttributes()); }
// controlla che il certificato del firmatario sia affidabile controllando la sua catena di // certificati // valida il certificato X509 del firmatario usando il built-in PKIX support messo a disposizione // da java // caricando il keystore contenente i certificati degli enti certificatori autorizzati dallo stato // italiano private PKIXCertPathBuilderResult isTrustedSigner(SignerInformation signer) throws FirmapiuException { // genera la lista di certificati da controllare per generare la catena dei certificati del // firmatario // TODO quali certificati carica esattamente? Collection<?> certCollection = certStore.getMatches(signer.getSID()); Iterator<?> certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder) certIt.next(); List<X509Certificate> chain = new LinkedList<X509Certificate>(); JcaX509CertificateConverter certConverter = new JcaX509CertificateConverter().setProvider(this.bcProvName); try { X509Certificate x509cert = certConverter.getCertificate(cert); chain.add(x509cert); while (certIt.hasNext()) { x509cert = certConverter.getCertificate((X509CertificateHolder) certIt.next()); chain.add(x509cert); } } catch (CertificateException e) { new FirmapiuException(CERT_DEFAULT_ERROR, e); } // carica i certificati presenti nel token crittografico passato come parametro KeyStore anchors = this.token.loadKeyStore(null); X509CertSelector target = new X509CertSelector(); target.setCertificate(chain.get(0)); PKIXBuilderParameters params; CertPathBuilder builder; try { params = new PKIXBuilderParameters(anchors, target); // disabilita il controllo delle CRL params.setRevocationEnabled(false); // se il certificato è scaduto cerca di generare lo stesso la catena dei certificati try { X509Certificate x509cert = certConverter.getCertificate(cert); // long before=x509cert.getNotBefore().getTime(); long after = x509cert.getNotAfter().getTime(); after -= 10; params.setDate(new Date(after)); } catch (CertificateException e) { throw new FirmapiuException(CERT_KEYSTORE_DEFAULT_ERROR, e); } CertStoreParameters intermediates = new CollectionCertStoreParameters(chain); params.addCertStore(CertStore.getInstance("Collection", intermediates)); params.setSigProvider(this.bcProvName); builder = CertPathBuilder.getInstance("PKIX", this.bcProvName); } catch (KeyStoreException | InvalidAlgorithmParameterException e) { throw new FirmapiuException(CERT_KEYSTORE_DEFAULT_ERROR, e); } catch (NoSuchAlgorithmException | NoSuchProviderException e) { throw new FirmapiuException(DEFAULT_ERROR, e); } /* * If build() returns successfully, the certificate is valid. More details * about the valid path can be obtained through the PKIXBuilderResult. * If no valid path can be found, a CertPathBuilderException is thrown. */ try { return (PKIXCertPathBuilderResult) builder.build(params); } catch (CertPathBuilderException e) { throw new FirmapiuException(VERIFY_SIGNER_CERTPATH_ERROR, e); } catch (InvalidAlgorithmParameterException e) { throw new FirmapiuException(DEFAULT_ERROR, e); } } // fine metodo
public SignerInformationStore getCounterSignatures() { return firstSignerInfo.getCounterSignatures(); }
/** * Verifica la correttezza della firma elettronica <b>di uno dei firmatari</b> della busta * crittografica controllando i campi di verifica richiesti come parametro * * @param signer il firmatario di cui bisogna verificare la firma * @param fields Una Set contenente i nomi dei campi che si vogliono verificare in fase di * operazione di verifica sul singolo firmatario * @return Una Map contenete il record dell'operazione di verifica sul firmatario con i campi * richiesti dal parametro fields * @see it.libersoft.firmapiu.consts.FirmapiuRecordConstants */ Map<String, Object> verifySigner(SignerInformation signer, Set<String> fields) { // genera la map contenente le informazioni di verifica per il singolo firmatario Map<String, Object> record = new TreeMap<String, Object>(); // FIXME informazione replicata nei metodi di Cades-Bes Verifier che già offrono la possbilità // di ottenere la SignerInformation // inserisce la signerinfo if (fields.contains(SIGNERINFO)) record.put(SIGNERINFO, signer); Collection<?> certCollection = certStore.getMatches(signer.getSID()); Iterator<?> certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder) certIt.next(); // inserisce il certificato del firmatario if (fields.contains(SIGNERCERT)) { try { X509Certificate x509cert = new JcaX509CertificateConverter().getCertificate(cert); record.put(SIGNERCERT, x509cert); } catch (CertificateException e) { record.put(SIGNERCERT, new FirmapiuException(CERT_DEFAULT_ERROR, e)); } } // inserisce la verifica della firma del firmatatio if (fields.contains(OKSIGNED)) { try { Boolean result = signer.verify( new JcaSimpleSignerInfoVerifierBuilder().setProvider(this.bcProvName).build(cert)); record.put(OKSIGNED, result); } catch (OperatorCreationException e) { record.put(OKSIGNED, new FirmapiuException(VERIFY_SIGNER_DEFAULT_ERROR, e)); } catch (CertificateException e) { record.put(OKSIGNED, new FirmapiuException(CERT_DEFAULT_ERROR, e)); } catch (CMSException e) { record.put(OKSIGNED, new FirmapiuException(VERIFY_SIGNER_DEFAULT_ERROR, e)); } // fine try-catch } // inserisce la verifica del controllo legale della firma di un firmatario if (fields.contains(LEGALLYSIGNED)) { try { record.put(LEGALLYSIGNED, new Boolean(isLegallySigned(signer, cert))); } catch (NoSuchAlgorithmException e) { record.put(LEGALLYSIGNED, new FirmapiuException(CERT_DEFAULT_ERROR, e)); } catch (FirmapiuException e) { record.put(LEGALLYSIGNED, e); } catch (IOException e) { record.put(LEGALLYSIGNED, new FirmapiuException(CERT_DEFAULT_ERROR, e)); } } // inserisce la verifica del controllo dell'affidabilità del certificato del firmatario PKIXCertPathBuilderResult signerCerthPathResult = null; if (fields.contains(TRUSTEDSIGNER)) { try { signerCerthPathResult = isTrustedSigner(signer); // se è arrivato a questo ramo di codice vuol dire che il certificato è affidbile record.put(TRUSTEDSIGNER, new Boolean(true)); } catch (FirmapiuException e) { record.put(TRUSTEDSIGNER, e); } } // inserisce la "trust anchor" del certificato del firmatario, ossia il certificato della CA che // lo ha emesso if (fields.contains(TRUSTANCHOR)) { try { if (signerCerthPathResult == null) signerCerthPathResult = isTrustedSigner(signer); X509Certificate trustanchor = signerCerthPathResult.getTrustAnchor().getTrustedCert(); record.put(TRUSTANCHOR, trustanchor); } catch (FirmapiuException e) { record.put(TRUSTANCHOR, e); } } // inserisce la catena di certificazione if (fields.contains(CERTCHAIN)) { try { if (signerCerthPathResult == null) signerCerthPathResult = isTrustedSigner(signer); List<? extends Certificate> certchain = signerCerthPathResult.getCertPath().getCertificates(); record.put(CERTCHAIN, certchain); } catch (FirmapiuException e) { record.put(CERTCHAIN, e); } } // verifica che il certificato relativo il firmatario non sia stato revocato // e che era valido al momento in cui i dati sono stati firmati Object certStatus = null; Date rvkdCertTime = null; if (fields.contains(SIGNERCERTSTATUS) || fields.contains(SIGNERCERTREVOKED)) { // controllo lo status del certificato utente con OSCP. Se il controllo fallisce o lo status // del certificato è "UNKNOWN" // esegue il controllo con le CRL X509Certificate userCertificate = null; try { userCertificate = new JcaX509CertificateConverter().getCertificate(cert); } catch (CertificateException e1) { if (fields.contains(SIGNERCERTSTATUS)) record.put(SIGNERCERTSTATUS, e1); if (fields.contains(SIGNERCERTREVOKED)) record.put(SIGNERCERTREVOKED, e1); } // se non è in grado di determinare lo user certificate di cui controllare lo status non deve // proseguire oltre if (userCertificate != null) { try { if (signerCerthPathResult == null) signerCerthPathResult = isTrustedSigner(signer); // TODO nota: non è detto che il trustanchor sia anche l'issuercertificate. Bisogna fare // un controllo mogliore X509Certificate issuerCertificate = signerCerthPathResult.getTrustAnchor().getTrustedCert(); certStatus = getCertificateStatus(userCertificate, issuerCertificate); // se certstatus è null il certificato è considerato valido if (certStatus == null) { if (fields.contains(SIGNERCERTSTATUS)) record.put(SIGNERCERTSTATUS, CertStatus.GOOD); if (fields.contains(SIGNERCERTREVOKED)) record.put(SIGNERCERTREVOKED, new Boolean(false)); } else { // se certStatus è una risposta ocsp if (certStatus instanceof CertificateStatus) { CertificateStatus c1 = (CertificateStatus) certStatus; if (c1 == CertificateStatus.GOOD) { if (fields.contains(SIGNERCERTSTATUS)) record.put(SIGNERCERTSTATUS, CertStatus.GOOD); if (fields.contains(SIGNERCERTREVOKED)) record.put(SIGNERCERTREVOKED, new Boolean(false)); } else // certificato revocato if (c1 instanceof RevokedStatus) { rvkdCertTime = ((RevokedStatus) c1).getRevocationTime(); if (fields.contains(SIGNERCERTSTATUS)) record.put(SIGNERCERTSTATUS, CertStatus.REVOKED); if (fields.contains(SIGNERCERTREVOKED)) { // controlla se il certificato era già revocato al signing time try { if (isRevokedAtSigningTime(signer, rvkdCertTime)) record.put(SIGNERCERTREVOKED, new Boolean(true)); else record.put(SIGNERCERTREVOKED, new Boolean(false)); } catch (FirmapiuException e) { record.put(SIGNERCERTREVOKED, e); } } // fine if (fields.contains(SIGNERCERTREVOKED) } // fine if (c1 instanceof RevokedStatus) } // se il certStatus è una risposta CRL vuol dire che il certificato è revocato, // altrimenti avrebbe restituito null else if (certStatus instanceof X509CRLEntry) { rvkdCertTime = ((X509CRLEntry) certStatus).getRevocationDate(); if (fields.contains(SIGNERCERTSTATUS)) record.put(SIGNERCERTSTATUS, CertStatus.REVOKED); if (fields.contains(SIGNERCERTREVOKED)) { // controlla se il certificato era già revocato al signing time try { if (isRevokedAtSigningTime(signer, rvkdCertTime)) record.put(SIGNERCERTREVOKED, new Boolean(true)); else record.put(SIGNERCERTREVOKED, new Boolean(false)); } catch (FirmapiuException e) { record.put(SIGNERCERTREVOKED, e); } } // fine if (fields.contains(SIGNERCERTREVOKED)) } // fine else if (certStatus instanceof X509CRLEntry) } // fine else } catch (FirmapiuException e) { record.put(SIGNERCERTSTATUS, e); } } // fine if (userCertificate!=null) } // fine if(fields.contains(SIGNERCERTSTATUS) | fields.contains(SIGNERCERTREVOKED)) // ritorna il record generato al chiamante return record; // OCSPVerify ocspVerifier=null; // if(fields.contains(SIGNERCERTSTATUS)){ // //controllo lo status del certificato utente con OSCP. Se il controllo fallisce o lo status // del certificato è "UNKNOWN" // //esegue il controllo con le CRL // X509Certificate userCertificate=null; // try { // userCertificate = new JcaX509CertificateConverter().getCertificate(cert); // } catch (CertificateException e1) { // record.put(SIGNERCERTSTATUS, e1); // } // //se non è in grado di determinare lo user certificate di cui controllare lo status non // deve proseguire oltre // if (userCertificate!=null) { // try { // if (signerCerthPathResult == null) // signerCerthPathResult = isTrustedSigner(signer); // //TODO nota: non è detto che il trustanchor sia anche l'issuercertificate. Bisogna fare // un controllo mogliore // X509Certificate issuerCertificate = signerCerthPathResult // .getTrustAnchor().getTrustedCert(); // ocspVerifier = new OCSPVerify(issuerCertificate, // userCertificate, this.bcProvName); // CertificateStatus certStatus = ocspVerifier // .getStatusCertificate(); // // certificato valido // if (certStatus == CertificateStatus.GOOD) { // record.put(SIGNERCERTSTATUS, CertStatus.GOOD); // } else // // certificato revocato // if (certStatus instanceof RevokedStatus) { // record.put(SIGNERCERTSTATUS, CertStatus.REVOKED); // } else // // stato del certificato sconosciuto // if (certStatus instanceof UnknownStatus) { // // System.out.println("certificato sconosciuto!"); // // System.err.println("OCSPVerify.getStatusResponse() " // // + "UnknowStatus"); // //return CertStatus.UNKNOWN; // //se lo stato del certificato è sconosciuto controlla anche le crl // CRLVerify crlVerifier = new CRLVerify(userCertificate); // try { // //TODO bisognerebbe controllare la firma delle risposte ricevute // if (crlVerifier.verifyCertificateCRLs()) // record.put(SIGNERCERTSTATUS, CertStatus.GOOD); // else // record.put(SIGNERCERTSTATUS, CertStatus.REVOKED); // } catch (FirmapiuException e) { // record.put(SIGNERCERTSTATUS, e); // } // }//fine if (certStatus instanceof UnknownStatus) // } catch (FirmapiuException e) { // //se il controllo tramite ocsp è fallito a causa di un errore, controlla anche le CRL // CRLVerify crlVerifier = new CRLVerify(userCertificate); // try { // //TODO bisognerebbe controllare la firma delle risposte ricevute // if (crlVerifier.verifyCertificateCRLs()) // record.put(SIGNERCERTSTATUS, CertStatus.GOOD); // else // record.put(SIGNERCERTSTATUS, CertStatus.REVOKED); // } catch (FirmapiuException e1) { // //TODO quale eccezione restituire? quella di OCSP o Quella di CRL? // record.put(SIGNERCERTSTATUS, e1); // } // }//fine try-catch // }//fine if (userCertificate!=null) // }//fine if(fields.contains(SIGNERCERTSTATUS)) }
public byte[] getEncodedSignedAttrs() throws IOException { return firstSignerInfo.getEncodedSignedAttributes(); }
@Test public void testCMSSignature() throws Exception { // setup byte[] toBeSigned = "hello world".getBytes(); String signatureDescription = "Test CMS Signature"; CMSTestSignatureService signatureService = new CMSTestSignatureService(toBeSigned, signatureDescription); KeyPair keyPair = PkiTestUtils.generateKeyPair(); DateTime notBefore = new DateTime(); DateTime notAfter = notBefore.plusYears(1); X509Certificate certificate = PkiTestUtils.generateCertificate( keyPair.getPublic(), "CN=Test", notBefore, notAfter, null, keyPair.getPrivate(), true, 0, null, null, new KeyUsage(KeyUsage.nonRepudiation)); List<X509Certificate> signingCertificateChain = new LinkedList<X509Certificate>(); signingCertificateChain.add(certificate); // operate DigestInfo digestInfo = signatureService.preSign(null, signingCertificateChain, null, null, null); // verify assertNotNull(digestInfo); byte[] digestValue = digestInfo.digestValue; LOG.debug("digest value: " + Hex.encodeHexString(digestValue)); assertNotNull(digestValue); assertEquals(signatureDescription, digestInfo.description); assertEquals("SHA1", digestInfo.digestAlgo); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPrivate()); byte[] digestInfoValue = ArrayUtils.addAll(PkiTestUtils.SHA1_DIGEST_INFO_PREFIX, digestValue); byte[] signatureValue = cipher.doFinal(digestInfoValue); LOG.debug("signature value: " + Hex.encodeHexString(signatureValue)); // operate signatureService.postSign(signatureValue, signingCertificateChain); // verify byte[] cmsSignature = signatureService.getCMSSignature(); CMSSignedData signedData = new CMSSignedData(cmsSignature); SignerInformationStore signers = signedData.getSignerInfos(); Iterator<SignerInformation> iter = signers.getSigners().iterator(); while (iter.hasNext()) { SignerInformation signer = iter.next(); SignerId signerId = signer.getSID(); assertTrue(signerId.match(certificate)); assertTrue(signer.verify(keyPair.getPublic(), BouncyCastleProvider.PROVIDER_NAME)); } byte[] data = (byte[]) signedData.getSignedContent().getContent(); assertArrayEquals(toBeSigned, data); }