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();
  }
Example #2
0
  /**
   * 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);
    }
  }
Example #3
0
  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);
    }
  }
Example #4
0
  /**
   * 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);
    }
  }
Example #6
0
  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);
    }
  }
Example #7
0
 /** return the ASN.1 encoded representation of this object. */
 public byte[] getEncoded() throws IOException {
   return contentInfo.getEncoded();
 }
Example #8
0
 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");
    }
  }
Example #10
0
  @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();
 }