private DERObject createDERForRecipient(byte[] in, X509Certificate cert) throws IOException, GeneralSecurityException { String s = "1.2.840.113549.3.2"; AlgorithmParameterGenerator algorithmparametergenerator = AlgorithmParameterGenerator.getInstance(s); AlgorithmParameters algorithmparameters = algorithmparametergenerator.generateParameters(); ByteArrayInputStream bytearrayinputstream = new ByteArrayInputStream(algorithmparameters.getEncoded("ASN.1")); ASN1InputStream asn1inputstream = new ASN1InputStream(bytearrayinputstream); DERObject derobject = asn1inputstream.readObject(); KeyGenerator keygenerator = KeyGenerator.getInstance(s); keygenerator.init(128); SecretKey secretkey = keygenerator.generateKey(); Cipher cipher = Cipher.getInstance(s); cipher.init(1, secretkey, algorithmparameters); byte[] abyte1 = cipher.doFinal(in); DEROctetString deroctetstring = new DEROctetString(abyte1); KeyTransRecipientInfo keytransrecipientinfo = computeRecipientInfo(cert, secretkey.getEncoded()); DERSet derset = new DERSet(new RecipientInfo(keytransrecipientinfo)); AlgorithmIdentifier algorithmidentifier = new AlgorithmIdentifier(new DERObjectIdentifier(s), derobject); EncryptedContentInfo encryptedcontentinfo = new EncryptedContentInfo(PKCSObjectIdentifiers.data, algorithmidentifier, deroctetstring); EnvelopedData env = new EnvelopedData(null, derset, encryptedcontentinfo, null); ContentInfo contentinfo = new ContentInfo(PKCSObjectIdentifiers.envelopedData, env); return contentinfo.getDERObject(); }
/** * Return the digested content * * @return the digested content * @throws CMSException if there is an exception un-compressing the data. */ public CMSProcessable getDigestedContent() throws CMSException { ContentInfo content = digestedData.getEncapContentInfo(); try { return new CMSProcessableByteArray( content.getContentType(), ((ASN1OctetString) content.getContent()).getOctets()); } catch (Exception e) { throw new CMSException("exception reading digested stream.", e); } }
public boolean verify(DigestCalculatorProvider calculatorProvider) throws CMSException { try { ContentInfo content = digestedData.getEncapContentInfo(); DigestCalculator calc = calculatorProvider.get(digestedData.getDigestAlgorithm()); OutputStream dOut = calc.getOutputStream(); dOut.write(((ASN1OctetString) content.getContent()).getOctets()); return Arrays.areEqual(digestedData.getDigest(), calc.getDigest()); } catch (OperatorCreationException e) { throw new CMSException("unable to create digest calculator: " + e.getMessage(), e); } catch (IOException e) { throw new CMSException("unable process content: " + e.getMessage(), e); } }
/** * Reads in a PKCS7 object. This returns a ContentInfo object suitable for use with the CMS API. * * @return the X509Certificate * @throws IOException if an I/O error occured */ private static CMSSignedData readPKCS7(BufferedReader in, char[] p, String endMarker) throws IOException { String line; StringBuffer buf = new StringBuffer(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); while ((line = in.readLine()) != null) { if (line.indexOf(endMarker) != -1) { break; } line = line.trim(); buf.append(line.trim()); Base64.decode(buf.substring(0, (buf.length() / 4) * 4), bOut); buf.delete(0, (buf.length() / 4) * 4); } if (buf.length() != 0) { throw new RuntimeException("base64 data appears to be truncated"); } if (line == null) { throw new IOException(endMarker + " not found"); } try { ASN1InputStream aIn = new ASN1InputStream(bOut.toByteArray()); return new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); } catch (Exception e) { throw new IOException("problem parsing PKCS7 object: " + e.toString()); } }
public void fromAsn1(byte[] data, int defaultCAKeyID) throws IOException, EIDException { try { ASN1InputStream ais = new ASN1InputStream(data); try { ASN1Sequence seq = (ASN1Sequence) ais.readObject(); ContentInfo ci = ContentInfo.getInstance(seq); if (!ci.getContentType().equals(CMSObjectIdentifiers.signedData)) throw new EIDException("wrong content type in CardSecurity"); SignedData sd = SignedData.getInstance((ASN1Sequence) ci.getContent()); ContentInfo eci = sd.getEncapContentInfo(); if (!eci.getContentType().equals(EAC2ObjectIdentifiers.id_SecurityObject)) throw new EIDException("CardSecurity does not encapsulate SecurityInfos"); SecurityInfos si = new SecurityInfos(); si.fromAsn1(((ASN1OctetString) eci.getContent()).getOctets(), defaultCAKeyID); securityInfos = si; } finally { ais.close(); } } catch (Exception e) { throw new EIDException(e); } }
public CMSDigestedData(ContentInfo contentInfo) throws CMSException { this.contentInfo = contentInfo; try { this.digestedData = DigestedData.getInstance(contentInfo.getContent()); } catch (ClassCastException e) { throw new CMSException("Malformed content.", e); } catch (IllegalArgumentException e) { throw new CMSException("Malformed content.", e); } }
/** return the ASN.1 encoded representation of this object. */ public byte[] getEncoded() throws IOException { return contentInfo.getEncoded(); }
public ASN1ObjectIdentifier getContentType() { return contentInfo.getContentType(); }
public void testCMSAlgorithmProtection() throws Exception { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); DigestCalculatorProvider calcProvider = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build(); byte[] kekId = new byte[] {1, 2, 3, 4, 5}; SecretKey kek = CMSTestUtil.makeDesede192Key(); adGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId, kek).setProvider(BC)); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build(), calcProvider.get(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1))); checkData(data, kek, ad); ContentInfo adInfo = ad.toASN1Structure(); AuthenticatedData iAd = AuthenticatedData.getInstance(adInfo.getContent().toASN1Primitive().getEncoded()); try { new CMSAuthenticatedData( new ContentInfo( CMSObjectIdentifiers.authenticatedData, new AuthenticatedData( iAd.getOriginatorInfo(), iAd.getRecipientInfos(), iAd.getMacAlgorithm(), new AlgorithmIdentifier(TeleTrusTObjectIdentifiers.ripemd160, DERNull.INSTANCE), iAd.getEncapsulatedContentInfo(), iAd.getAuthAttrs(), iAd.getMac(), iAd.getUnauthAttrs())), calcProvider); } catch (CMSException e) { Assert.assertEquals( e.getMessage(), "CMS Algorithm Identifier Protection check failed for digestAlgorithm"); } AlgorithmIdentifier newDigAlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); Assert.assertFalse(iAd.getDigestAlgorithm().equals(newDigAlgId)); checkData( data, kek, new CMSAuthenticatedData( new ContentInfo( CMSObjectIdentifiers.authenticatedData, new AuthenticatedData( iAd.getOriginatorInfo(), iAd.getRecipientInfos(), iAd.getMacAlgorithm(), newDigAlgId, iAd.getEncapsulatedContentInfo(), iAd.getAuthAttrs(), iAd.getMac(), iAd.getUnauthAttrs())), calcProvider)); try { new CMSAuthenticatedData( new ContentInfo( CMSObjectIdentifiers.authenticatedData, new AuthenticatedData( iAd.getOriginatorInfo(), iAd.getRecipientInfos(), new AlgorithmIdentifier(CMSAlgorithm.AES192_CBC), iAd.getDigestAlgorithm(), iAd.getEncapsulatedContentInfo(), iAd.getAuthAttrs(), iAd.getMac(), iAd.getUnauthAttrs())), calcProvider); } catch (CMSException e) { Assert.assertEquals( e.getMessage(), "CMS Algorithm Identifier Protection check failed for macAlgorithm"); } try { AlgorithmIdentifier newMacAlgId = new AlgorithmIdentifier(CMSAlgorithm.DES_EDE3_CBC); Assert.assertFalse(iAd.getMacAlgorithm().equals(newMacAlgId)); new CMSAuthenticatedData( new ContentInfo( CMSObjectIdentifiers.authenticatedData, new AuthenticatedData( iAd.getOriginatorInfo(), iAd.getRecipientInfos(), newMacAlgId, iAd.getDigestAlgorithm(), iAd.getEncapsulatedContentInfo(), iAd.getAuthAttrs(), iAd.getMac(), iAd.getUnauthAttrs())), calcProvider); } catch (CMSException e) { Assert.assertEquals( e.getMessage(), "CMS Algorithm Identifier Protection check failed for macAlgorithm"); } }
@Override protected void onDocumentSigned(byte[] byteArray) { try { InputStream inputStream = new ByteArrayInputStream(byteArray); PDDocument document = PDDocument.load(inputStream); List<PDSignature> signatures = document.getSignatureDictionaries(); assertEquals(1, signatures.size()); for (PDSignature pdSignature : signatures) { byte[] contents = pdSignature.getContents(byteArray); byte[] signedContent = pdSignature.getSignedContent(byteArray); logger.info("Byte range : " + Arrays.toString(pdSignature.getByteRange())); // IOUtils.write(contents, new FileOutputStream("sig.p7s")); ASN1InputStream asn1sInput = new ASN1InputStream(contents); ASN1Sequence asn1Seq = (ASN1Sequence) asn1sInput.readObject(); logger.info("SEQ : " + asn1Seq.toString()); ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(asn1Seq.getObjectAt(0)); assertEquals(PKCSObjectIdentifiers.signedData, oid); SignedData signedData = SignedData.getInstance(DERTaggedObject.getInstance(asn1Seq.getObjectAt(1)).getObject()); ASN1Set digestAlgorithmSet = signedData.getDigestAlgorithms(); ASN1ObjectIdentifier oidDigestAlgo = ASN1ObjectIdentifier.getInstance( ASN1Sequence.getInstance(digestAlgorithmSet.getObjectAt(0)).getObjectAt(0)); DigestAlgorithm digestAlgorithm = DigestAlgorithm.forOID(oidDigestAlgo.getId()); logger.info("DIGEST ALGO : " + digestAlgorithm); ContentInfo encapContentInfo = signedData.getEncapContentInfo(); ASN1ObjectIdentifier contentTypeOID = encapContentInfo.getContentType(); logger.info("ENCAPSULATED CONTENT INFO TYPE : " + contentTypeOID); assertEquals(PKCSObjectIdentifiers.data, contentTypeOID); ASN1Encodable content = encapContentInfo.getContent(); logger.info("ENCAPSULATED CONTENT INFO CONTENT : " + content); assertNull(content); List<X509Certificate> certificates = extractCertificates(signedData); ASN1Set signerInfosAsn1 = signedData.getSignerInfos(); logger.info("SIGNER INFO ASN1 : " + signerInfosAsn1.toString()); SignerInfo signedInfo = SignerInfo.getInstance(ASN1Sequence.getInstance(signerInfosAsn1.getObjectAt(0))); ASN1Set authenticatedAttributeSet = signedInfo.getAuthenticatedAttributes(); logger.info("AUTHENTICATED ATTR : " + authenticatedAttributeSet); List<ASN1ObjectIdentifier> attributeOids = new ArrayList<ASN1ObjectIdentifier>(); for (int i = 0; i < authenticatedAttributeSet.size(); i++) { Attribute attribute = Attribute.getInstance(authenticatedAttributeSet.getObjectAt(i)); attributeOids.add(attribute.getAttrType()); } logger.info("List of OID for Auth Attrb : " + attributeOids); Attribute attributeDigest = Attribute.getInstance(authenticatedAttributeSet.getObjectAt(1)); assertEquals(PKCSObjectIdentifiers.pkcs_9_at_messageDigest, attributeDigest.getAttrType()); ASN1OctetString asn1ObjString = ASN1OctetString.getInstance(attributeDigest.getAttrValues().getObjectAt(0)); String embeddedDigest = Base64.encode(asn1ObjString.getOctets()); logger.info("MESSAGE DIGEST : " + embeddedDigest); byte[] digestSignedContent = DSSUtils.digest(digestAlgorithm, signedContent); String computedDigestSignedContentEncodeBase64 = Base64.encode(digestSignedContent); logger.info( "COMPUTED DIGEST SIGNED CONTENT BASE64 : " + computedDigestSignedContentEncodeBase64); assertEquals(embeddedDigest, computedDigestSignedContentEncodeBase64); SignerIdentifier sid = signedInfo.getSID(); logger.info("SIGNER IDENTIFIER : " + sid.getId()); IssuerAndSerialNumber issuerAndSerialNumber = IssuerAndSerialNumber.getInstance(signedInfo.getSID()); ASN1Integer signerSerialNumber = issuerAndSerialNumber.getSerialNumber(); logger.info( "ISSUER AND SN : " + issuerAndSerialNumber.getName() + " " + signerSerialNumber); BigInteger serial = issuerAndSerialNumber.getSerialNumber().getValue(); X509Certificate signerCertificate = null; for (X509Certificate x509Certificate : certificates) { if (serial.equals(x509Certificate.getSerialNumber())) { signerCertificate = x509Certificate; } } assertNotNull(signerCertificate); String algorithm = signerCertificate.getPublicKey().getAlgorithm(); EncryptionAlgorithm encryptionAlgorithm = EncryptionAlgorithm.forName(algorithm); ASN1OctetString encryptedInfoOctedString = signedInfo.getEncryptedDigest(); String signatureValue = Hex.toHexString(encryptedInfoOctedString.getOctets()); logger.info("SIGNATURE VALUE : " + signatureValue); Cipher cipher = Cipher.getInstance(encryptionAlgorithm.getName()); cipher.init(Cipher.DECRYPT_MODE, signerCertificate); byte[] decrypted = cipher.doFinal(encryptedInfoOctedString.getOctets()); ASN1InputStream inputDecrypted = new ASN1InputStream(decrypted); ASN1Sequence seqDecrypt = (ASN1Sequence) inputDecrypted.readObject(); logger.info("DECRYPTED : " + seqDecrypt); DigestInfo digestInfo = new DigestInfo(seqDecrypt); assertEquals(oidDigestAlgo, digestInfo.getAlgorithmId().getAlgorithm()); String decryptedDigestEncodeBase64 = Base64.encode(digestInfo.getDigest()); logger.info("DECRYPTED BASE64 : " + decryptedDigestEncodeBase64); byte[] encoded = authenticatedAttributeSet.getEncoded(); byte[] digest = DSSUtils.digest(digestAlgorithm, encoded); String computedDigestFromSignatureEncodeBase64 = Base64.encode(digest); logger.info( "COMPUTED DIGEST FROM SIGNATURE BASE64 : " + computedDigestFromSignatureEncodeBase64); assertEquals(decryptedDigestEncodeBase64, computedDigestFromSignatureEncodeBase64); IOUtils.closeQuietly(inputDecrypted); IOUtils.closeQuietly(asn1sInput); } IOUtils.closeQuietly(inputStream); document.close(); } catch (Exception e) { logger.error(e.getMessage(), e); fail(e.getMessage()); } }
public ASN1ObjectIdentifier getContentType() { ContentInfo ci = cmsSignedData.getContentInfo(); if (ci == null) return null; return ci.getContentType(); }