Search in sources :

Example 21 with SignerInformation

use of org.bouncycastle.cms.SignerInformation in project xipki by xipki.

the class DecodedPkiMessage method decode.

@SuppressWarnings("unchecked")
public static DecodedPkiMessage decode(CMSSignedData pkiMessage, EnvelopedDataDecryptor recipient, CollectionStore<X509CertificateHolder> certStore) throws MessageDecodingException {
    ScepUtil.requireNonNull("pkiMessage", pkiMessage);
    ScepUtil.requireNonNull("recipient", recipient);
    SignerInformationStore signerStore = pkiMessage.getSignerInfos();
    Collection<SignerInformation> signerInfos = signerStore.getSigners();
    if (signerInfos.size() != 1) {
        throw new MessageDecodingException("number of signerInfos is not 1, but " + signerInfos.size());
    }
    SignerInformation signerInfo = signerInfos.iterator().next();
    SignerId sid = signerInfo.getSID();
    Collection<?> signedDataCerts = null;
    if (certStore != null) {
        signedDataCerts = certStore.getMatches(sid);
    }
    if (signedDataCerts == null || signedDataCerts.isEmpty()) {
        signedDataCerts = pkiMessage.getCertificates().getMatches(signerInfo.getSID());
    }
    if (signedDataCerts == null || signedDataCerts.size() != 1) {
        throw new MessageDecodingException("could not find embedded certificate to verify the signature");
    }
    AttributeTable signedAttrs = signerInfo.getSignedAttributes();
    if (signedAttrs == null) {
        throw new MessageDecodingException("missing SCEP attributes");
    }
    Date signingTime = null;
    // signingTime
    ASN1Encodable attrValue = ScepUtil.getFirstAttrValue(signedAttrs, CMSAttributes.signingTime);
    if (attrValue != null) {
        signingTime = Time.getInstance(attrValue).getDate();
    }
    // transactionId
    String str = getPrintableStringAttrValue(signedAttrs, ScepObjectIdentifiers.ID_TRANSACTION_ID);
    if (str == null || str.isEmpty()) {
        throw new MessageDecodingException("missing required SCEP attribute transactionId");
    }
    TransactionId transactionId = new TransactionId(str);
    // messageType
    Integer intValue = getIntegerPrintStringAttrValue(signedAttrs, ScepObjectIdentifiers.ID_MESSAGE_TYPE);
    if (intValue == null) {
        throw new MessageDecodingException("tid " + transactionId.getId() + ": missing required SCEP attribute messageType");
    }
    MessageType messageType;
    try {
        messageType = MessageType.forValue(intValue);
    } catch (IllegalArgumentException ex) {
        throw new MessageDecodingException("tid " + transactionId.getId() + ": invalid messageType '" + intValue + "'");
    }
    // senderNonce
    Nonce senderNonce = getNonceAttrValue(signedAttrs, ScepObjectIdentifiers.ID_SENDER_NONCE);
    if (senderNonce == null) {
        throw new MessageDecodingException("tid " + transactionId.getId() + ": missing required SCEP attribute senderNonce");
    }
    DecodedPkiMessage ret = new DecodedPkiMessage(transactionId, messageType, senderNonce);
    if (signingTime != null) {
        ret.setSigningTime(signingTime);
    }
    Nonce recipientNonce = null;
    try {
        recipientNonce = getNonceAttrValue(signedAttrs, ScepObjectIdentifiers.ID_RECIPIENT_NONCE);
    } catch (MessageDecodingException ex) {
        ret.setFailureMessage("could not parse recipientNonce: " + ex.getMessage());
    }
    if (recipientNonce != null) {
        ret.setRecipientNonce(recipientNonce);
    }
    PkiStatus pkiStatus = null;
    FailInfo failInfo = null;
    if (MessageType.CertRep == messageType) {
        // pkiStatus
        try {
            intValue = getIntegerPrintStringAttrValue(signedAttrs, ScepObjectIdentifiers.ID_PKI_STATUS);
        } catch (MessageDecodingException ex) {
            ret.setFailureMessage("could not parse pkiStatus: " + ex.getMessage());
            return ret;
        }
        if (intValue == null) {
            ret.setFailureMessage("missing required SCEP attribute pkiStatus");
            return ret;
        }
        try {
            pkiStatus = PkiStatus.forValue(intValue);
        } catch (IllegalArgumentException ex) {
            ret.setFailureMessage("invalid pkiStatus '" + intValue + "'");
            return ret;
        }
        ret.setPkiStatus(pkiStatus);
        // failureInfo
        if (pkiStatus == PkiStatus.FAILURE) {
            try {
                intValue = getIntegerPrintStringAttrValue(signedAttrs, ScepObjectIdentifiers.ID_FAILINFO);
            } catch (MessageDecodingException ex) {
                ret.setFailureMessage("could not parse failInfo: " + ex.getMessage());
                return ret;
            }
            if (intValue == null) {
                ret.setFailureMessage("missing required SCEP attribute failInfo");
                return ret;
            }
            try {
                failInfo = FailInfo.forValue(intValue);
            } catch (IllegalArgumentException ex) {
                ret.setFailureMessage("invalid failInfo '" + intValue + "'");
                return ret;
            }
            ret.setFailInfo(failInfo);
        }
    // end if(pkiStatus == PkiStatus.FAILURE)
    }
    // end if (MessageType.CertRep == messageType)
    // other signedAttributes
    Attribute[] attrs = signedAttrs.toASN1Structure().getAttributes();
    for (Attribute attr : attrs) {
        ASN1ObjectIdentifier type = attr.getAttrType();
        if (!SCEP_ATTR_TYPES.contains(type)) {
            ret.addSignendAttribute(type, attr.getAttrValues().getObjectAt(0));
        }
    }
    // unsignedAttributes
    AttributeTable unsignedAttrs = signerInfo.getUnsignedAttributes();
    attrs = (unsignedAttrs == null) ? null : unsignedAttrs.toASN1Structure().getAttributes();
    if (attrs != null) {
        for (Attribute attr : attrs) {
            ASN1ObjectIdentifier type = attr.getAttrType();
            ret.addUnsignendAttribute(type, attr.getAttrValues().getObjectAt(0));
        }
    }
    ASN1ObjectIdentifier digestAlgOid = signerInfo.getDigestAlgorithmID().getAlgorithm();
    ret.setDigestAlgorithm(digestAlgOid);
    String sigAlgOid = signerInfo.getEncryptionAlgOID();
    if (!PKCSObjectIdentifiers.rsaEncryption.getId().equals(sigAlgOid)) {
        ASN1ObjectIdentifier tmpDigestAlgOid;
        try {
            tmpDigestAlgOid = ScepUtil.extractDigesetAlgorithmIdentifier(signerInfo.getEncryptionAlgOID(), signerInfo.getEncryptionAlgParams());
        } catch (Exception ex) {
            final String msg = "could not extract digest algorithm from signerInfo.signatureAlgorithm: " + ex.getMessage();
            LOG.error(msg);
            LOG.debug(msg, ex);
            ret.setFailureMessage(msg);
            return ret;
        }
        if (!digestAlgOid.equals(tmpDigestAlgOid)) {
            ret.setFailureMessage("digestAlgorithm and encryptionAlgorithm do not use the same digestAlgorithm");
            return ret;
        }
    // end if
    }
    // end if
    X509CertificateHolder tmpSignerCert = (X509CertificateHolder) signedDataCerts.iterator().next();
    X509Certificate signerCert;
    try {
        signerCert = ScepUtil.toX509Cert(tmpSignerCert.toASN1Structure());
    } catch (CertificateException ex) {
        final String msg = "could not construct X509Certificate: " + ex.getMessage();
        LOG.error(msg);
        LOG.debug(msg, ex);
        ret.setFailureMessage(msg);
        return ret;
    }
    ret.setSignatureCert(signerCert);
    // validate the signature
    SignerInformationVerifier verifier;
    try {
        verifier = new JcaSimpleSignerInfoVerifierBuilder().build(tmpSignerCert);
    } catch (OperatorCreationException | CertificateException ex) {
        final String msg = "could not build signature verifier: " + ex.getMessage();
        LOG.error(msg);
        LOG.debug(msg, ex);
        ret.setFailureMessage(msg);
        return ret;
    }
    boolean signatureValid;
    try {
        signatureValid = signerInfo.verify(verifier);
    } catch (CMSException ex) {
        final String msg = "could not verify the signature: " + ex.getMessage();
        LOG.error(msg);
        LOG.debug(msg, ex);
        ret.setFailureMessage(msg);
        return ret;
    }
    ret.setSignatureValid(signatureValid);
    if (!signatureValid) {
        return ret;
    }
    if (MessageType.CertRep == messageType && (pkiStatus == PkiStatus.FAILURE | pkiStatus == PkiStatus.PENDING)) {
        return ret;
    }
    // MessageData
    CMSTypedData signedContent = pkiMessage.getSignedContent();
    ASN1ObjectIdentifier signedContentType = signedContent.getContentType();
    if (!CMSObjectIdentifiers.envelopedData.equals(signedContentType)) {
        // fall back: some SCEP client, such as JSCEP use id-data
        if (!CMSObjectIdentifiers.data.equals(signedContentType)) {
            ret.setFailureMessage("either id-envelopedData or id-data is excepted, but not '" + signedContentType.getId());
            return ret;
        }
    }
    CMSEnvelopedData envData;
    try {
        envData = new CMSEnvelopedData((byte[]) signedContent.getContent());
    } catch (CMSException ex) {
        final String msg = "could not create the CMSEnvelopedData: " + ex.getMessage();
        LOG.error(msg);
        LOG.debug(msg, ex);
        ret.setFailureMessage(msg);
        return ret;
    }
    ret.setContentEncryptionAlgorithm(envData.getContentEncryptionAlgorithm().getAlgorithm());
    byte[] encodedMessageData;
    try {
        encodedMessageData = recipient.decrypt(envData);
    } catch (MessageDecodingException ex) {
        final String msg = "could not create the CMSEnvelopedData: " + ex.getMessage();
        LOG.error(msg);
        LOG.debug(msg, ex);
        ret.setFailureMessage(msg);
        ret.setDecryptionSuccessful(false);
        return ret;
    }
    ret.setDecryptionSuccessful(true);
    try {
        if (MessageType.PKCSReq == messageType || MessageType.RenewalReq == messageType || MessageType.UpdateReq == messageType) {
            CertificationRequest messageData = CertificationRequest.getInstance(encodedMessageData);
            ret.setMessageData(messageData);
        } else if (MessageType.CertPoll == messageType) {
            IssuerAndSubject messageData = IssuerAndSubject.getInstance(encodedMessageData);
            ret.setMessageData(messageData);
        } else if (MessageType.GetCert == messageType || MessageType.GetCRL == messageType) {
            IssuerAndSerialNumber messageData = IssuerAndSerialNumber.getInstance(encodedMessageData);
            ret.setMessageData(messageData);
            ret.setMessageData(messageData);
        } else if (MessageType.CertRep == messageType) {
            ContentInfo ci = ContentInfo.getInstance(encodedMessageData);
            ret.setMessageData(ci);
        } else {
            throw new RuntimeException("should not reach here, unknown messageType " + messageType);
        }
    } catch (Exception ex) {
        final String msg = "could not parse the messageData: " + ex.getMessage();
        LOG.error(msg);
        LOG.debug(msg, ex);
        ret.setFailureMessage(msg);
        return ret;
    }
    return ret;
}
Also used : IssuerAndSerialNumber(org.bouncycastle.asn1.cms.IssuerAndSerialNumber) Attribute(org.bouncycastle.asn1.cms.Attribute) AttributeTable(org.bouncycastle.asn1.cms.AttributeTable) SignerInformation(org.bouncycastle.cms.SignerInformation) CertificateException(java.security.cert.CertificateException) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DERPrintableString(org.bouncycastle.asn1.DERPrintableString) SignerInformationStore(org.bouncycastle.cms.SignerInformationStore) ContentInfo(org.bouncycastle.asn1.cms.ContentInfo) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) FailInfo(org.xipki.scep.transaction.FailInfo) SignerInformationVerifier(org.bouncycastle.cms.SignerInformationVerifier) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) MessageType(org.xipki.scep.transaction.MessageType) PkiStatus(org.xipki.scep.transaction.PkiStatus) CMSEnvelopedData(org.bouncycastle.cms.CMSEnvelopedData) CMSTypedData(org.bouncycastle.cms.CMSTypedData) JcaSimpleSignerInfoVerifierBuilder(org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder) Date(java.util.Date) CMSException(org.bouncycastle.cms.CMSException) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) MessageDecodingException(org.xipki.scep.exception.MessageDecodingException) CertificateException(java.security.cert.CertificateException) X509Certificate(java.security.cert.X509Certificate) TransactionId(org.xipki.scep.transaction.TransactionId) Nonce(org.xipki.scep.transaction.Nonce) MessageDecodingException(org.xipki.scep.exception.MessageDecodingException) SignerId(org.bouncycastle.cms.SignerId) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) CertificationRequest(org.bouncycastle.asn1.pkcs.CertificationRequest) CMSException(org.bouncycastle.cms.CMSException)

Example 22 with SignerInformation

use of org.bouncycastle.cms.SignerInformation in project xipki by xipki.

the class DecodedNextCaMessage method decode.

@SuppressWarnings("unchecked")
public static DecodedNextCaMessage decode(CMSSignedData pkiMessage, CollectionStore<X509CertificateHolder> certStore) throws MessageDecodingException {
    ScepUtil.requireNonNull("pkiMessage", pkiMessage);
    SignerInformationStore signerStore = pkiMessage.getSignerInfos();
    Collection<SignerInformation> signerInfos = signerStore.getSigners();
    if (signerInfos.size() != 1) {
        throw new MessageDecodingException("number of signerInfos is not 1, but " + signerInfos.size());
    }
    SignerInformation signerInfo = signerInfos.iterator().next();
    SignerId sid = signerInfo.getSID();
    Collection<?> signedDataCerts = null;
    if (certStore != null) {
        signedDataCerts = certStore.getMatches(sid);
    }
    if (signedDataCerts == null || signedDataCerts.isEmpty()) {
        signedDataCerts = pkiMessage.getCertificates().getMatches(signerInfo.getSID());
    }
    if (signedDataCerts == null || signedDataCerts.size() != 1) {
        throw new MessageDecodingException("could not find embedded certificate to verify the signature");
    }
    AttributeTable signedAttrs = signerInfo.getSignedAttributes();
    if (signedAttrs == null) {
        throw new MessageDecodingException("missing signed attributes");
    }
    Date signingTime = null;
    // signingTime
    ASN1Encodable attrValue = ScepUtil.getFirstAttrValue(signedAttrs, CMSAttributes.signingTime);
    if (attrValue != null) {
        signingTime = Time.getInstance(attrValue).getDate();
    }
    DecodedNextCaMessage ret = new DecodedNextCaMessage();
    if (signingTime != null) {
        ret.setSigningTime(signingTime);
    }
    ASN1ObjectIdentifier digestAlgOid = signerInfo.getDigestAlgorithmID().getAlgorithm();
    ret.setDigestAlgorithm(digestAlgOid);
    String sigAlgOid = signerInfo.getEncryptionAlgOID();
    if (!PKCSObjectIdentifiers.rsaEncryption.getId().equals(sigAlgOid)) {
        ASN1ObjectIdentifier tmpDigestAlgOid;
        try {
            tmpDigestAlgOid = ScepUtil.extractDigesetAlgorithmIdentifier(signerInfo.getEncryptionAlgOID(), signerInfo.getEncryptionAlgParams());
        } catch (Exception ex) {
            final String msg = "could not extract digest algorithm from signerInfo.signatureAlgorithm: " + ex.getMessage();
            LOG.error(msg);
            LOG.debug(msg, ex);
            ret.setFailureMessage(msg);
            return ret;
        }
        if (!digestAlgOid.equals(tmpDigestAlgOid)) {
            ret.setFailureMessage("digestAlgorithm and encryptionAlgorithm do not use" + " the same digestAlgorithm");
            return ret;
        }
    }
    // end if
    X509CertificateHolder tmpSignerCert = (X509CertificateHolder) signedDataCerts.iterator().next();
    X509Certificate signerCert;
    try {
        signerCert = ScepUtil.toX509Cert(tmpSignerCert.toASN1Structure());
    } catch (CertificateException ex) {
        final String msg = "could not construct X509CertificateObject: " + ex.getMessage();
        LOG.error(msg);
        LOG.debug(msg, ex);
        ret.setFailureMessage(msg);
        return ret;
    }
    ret.setSignatureCert(signerCert);
    // validate the signature
    SignerInformationVerifier verifier;
    try {
        verifier = new JcaSimpleSignerInfoVerifierBuilder().build(signerCert.getPublicKey());
    } catch (OperatorCreationException ex) {
        final String msg = "could not build signature verifier: " + ex.getMessage();
        LOG.error(msg);
        LOG.debug(msg, ex);
        ret.setFailureMessage(msg);
        return ret;
    }
    boolean signatureValid;
    try {
        signatureValid = signerInfo.verify(verifier);
    } catch (CMSException ex) {
        final String msg = "could not verify the signature: " + ex.getMessage();
        LOG.error(msg);
        LOG.debug(msg, ex);
        ret.setFailureMessage(msg);
        return ret;
    }
    ret.setSignatureValid(signatureValid);
    if (!signatureValid) {
        return ret;
    }
    // MessageData
    CMSTypedData signedContent = pkiMessage.getSignedContent();
    ASN1ObjectIdentifier signedContentType = signedContent.getContentType();
    if (!CMSObjectIdentifiers.signedData.equals(signedContentType)) {
        // fall back: some SCEP client use id-data
        if (!CMSObjectIdentifiers.data.equals(signedContentType)) {
            ret.setFailureMessage("either id-signedData or id-data is excepted, but not '" + signedContentType.getId());
            return ret;
        }
    }
    ContentInfo contentInfo = ContentInfo.getInstance((byte[]) signedContent.getContent());
    SignedData signedData = SignedData.getInstance(contentInfo.getContent());
    List<X509Certificate> certs;
    try {
        certs = ScepUtil.getCertsFromSignedData(signedData);
    } catch (CertificateException ex) {
        final String msg = "could not extract Certificates from the message: " + ex.getMessage();
        LOG.error(msg);
        LOG.debug(msg, ex);
        ret.setFailureMessage(msg);
        return ret;
    }
    final int n = certs.size();
    X509Certificate caCert = null;
    List<X509Certificate> raCerts = new LinkedList<X509Certificate>();
    for (int i = 0; i < n; i++) {
        X509Certificate cert = certs.get(i);
        if (cert.getBasicConstraints() > -1) {
            if (caCert != null) {
                final String msg = "multiple CA certificates is returned, but exactly 1 is expected";
                LOG.error(msg);
                ret.setFailureMessage(msg);
                return ret;
            }
            caCert = cert;
        } else {
            raCerts.add(cert);
        }
    }
    if (caCert == null) {
        final String msg = "no CA certificate is returned";
        LOG.error(msg);
        ret.setFailureMessage(msg);
        return ret;
    }
    X509Certificate[] locaRaCerts = raCerts.isEmpty() ? null : raCerts.toArray(new X509Certificate[0]);
    AuthorityCertStore authorityCertStore = AuthorityCertStore.getInstance(caCert, locaRaCerts);
    ret.setAuthorityCertStore(authorityCertStore);
    return ret;
}
Also used : AttributeTable(org.bouncycastle.asn1.cms.AttributeTable) SignerInformation(org.bouncycastle.cms.SignerInformation) CertificateException(java.security.cert.CertificateException) SignerInformationStore(org.bouncycastle.cms.SignerInformationStore) ContentInfo(org.bouncycastle.asn1.cms.ContentInfo) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) SignerInformationVerifier(org.bouncycastle.cms.SignerInformationVerifier) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) CMSTypedData(org.bouncycastle.cms.CMSTypedData) SignedData(org.bouncycastle.asn1.cms.SignedData) CMSSignedData(org.bouncycastle.cms.CMSSignedData) JcaSimpleSignerInfoVerifierBuilder(org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder) Date(java.util.Date) CMSException(org.bouncycastle.cms.CMSException) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) MessageDecodingException(org.xipki.scep.exception.MessageDecodingException) CertificateException(java.security.cert.CertificateException) X509Certificate(java.security.cert.X509Certificate) LinkedList(java.util.LinkedList) MessageDecodingException(org.xipki.scep.exception.MessageDecodingException) SignerId(org.bouncycastle.cms.SignerId) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) CMSException(org.bouncycastle.cms.CMSException)

Example 23 with SignerInformation

use of org.bouncycastle.cms.SignerInformation in project signer by demoiselle.

the class CAdESSigner method doCounterSign.

@Override
public byte[] doCounterSign(byte[] previewCMSSignature) {
    try {
        Security.addProvider(new BouncyCastleProvider());
        // Reading a P7S file that is preview signature.
        CMSSignedData cmsPreviewSignedData = new CMSSignedData(previewCMSSignature);
        // Build BouncyCastle object that is a set of signatures
        Collection<SignerInformation> previewSigners = cmsPreviewSignedData.getSignerInfos().getSigners();
        for (SignerInformation previewSigner : previewSigners) {
            // build a counter-signature per previewSignature
            byte[] previewSignatureFromSigner = previewSigner.getSignature();
            CMSSignedData cmsCounterSignedData = new CMSSignedData(this.doSign(previewSignatureFromSigner));
            cmsPreviewSignedData = this.updateWithCounterSignature(cmsCounterSignedData, cmsPreviewSignedData, previewSigner.getSID());
        }
        return cmsPreviewSignedData.getEncoded();
    } catch (Throwable error) {
        throw new SignerException(error);
    }
}
Also used : SignerInformation(org.bouncycastle.cms.SignerInformation) CMSSignedData(org.bouncycastle.cms.CMSSignedData) SignerException(org.demoiselle.signer.policy.impl.cades.SignerException) BouncyCastleProvider(org.bouncycastle.jce.provider.BouncyCastleProvider)

Example 24 with SignerInformation

use of org.bouncycastle.cms.SignerInformation in project signer by demoiselle.

the class CAdESSigner method getSignersCertificates.

private Collection<X509Certificate> getSignersCertificates(CMSSignedData previewSignerData) {
    Collection<X509Certificate> result = new HashSet<X509Certificate>();
    Store<?> certStore = previewSignerData.getCertificates();
    SignerInformationStore signers = previewSignerData.getSignerInfos();
    Iterator<?> it = signers.getSigners().iterator();
    while (it.hasNext()) {
        SignerInformation signer = (SignerInformation) it.next();
        @SuppressWarnings("unchecked") Collection<?> certCollection = certStore.getMatches(signer.getSID());
        Iterator<?> certIt = certCollection.iterator();
        X509CertificateHolder certificateHolder = (X509CertificateHolder) certIt.next();
        try {
            result.add(new JcaX509CertificateConverter().getCertificate(certificateHolder));
        } catch (CertificateException error) {
        }
    }
    return result;
}
Also used : SignerInformationStore(org.bouncycastle.cms.SignerInformationStore) JcaX509CertificateConverter(org.bouncycastle.cert.jcajce.JcaX509CertificateConverter) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) SignerInformation(org.bouncycastle.cms.SignerInformation) CertificateException(java.security.cert.CertificateException) X509Certificate(java.security.cert.X509Certificate) HashSet(java.util.HashSet)

Example 25 with SignerInformation

use of org.bouncycastle.cms.SignerInformation in project signer by demoiselle.

the class CAdESSigner method doSign.

private byte[] doSign(byte[] content, byte[] previewSignature) {
    try {
        Security.addProvider(new BouncyCastleProvider());
        // Completa os certificados ausentes da cadeia, se houver
        if (this.certificate == null && this.certificateChain != null && this.certificateChain.length > 0) {
            this.certificate = (X509Certificate) this.certificateChain[0];
        }
        this.certificateChain = CAManager.getInstance().getCertificateChainArray(this.certificate);
        if (this.certificateChain.length < 3) {
            throw new SignerException(cadesMessagesBundle.getString("error.no.ca", this.certificate.getIssuerDN()));
        }
        Certificate[] certStore = new Certificate[] {};
        CMSSignedData cmsPreviewSignedData = null;
        // Importar todos os certificados da assinatura anterior
        if (previewSignature != null && previewSignature.length > 0) {
            cmsPreviewSignedData = new CMSSignedData(new CMSAbsentContent(), previewSignature);
            Collection<X509Certificate> previewCerts = this.getSignersCertificates(cmsPreviewSignedData);
            // previewCerts.add(this.certificate);
            certStore = previewCerts.toArray(new Certificate[] {});
        }
        setCertificateManager(new CertificateManager(this.certificate));
        // Recupera a lista de algoritmos da politica e o tamanho minimo da
        // chave
        List<AlgAndLength> listOfAlgAndLength = new ArrayList<AlgAndLength>();
        for (AlgAndLength algLength : signaturePolicy.getSignPolicyInfo().getSignatureValidationPolicy().getCommonRules().getAlgorithmConstraintSet().getSignerAlgorithmConstraints().getAlgAndLengths()) {
            listOfAlgAndLength.add(algLength);
        }
        AlgAndLength algAndLength = null;
        // verificar se o mesmo é permitido pela politica
        if (this.pkcs1.getAlgorithm() != null) {
            String varSetedAlgorithmOID = AlgorithmNames.getOIDByAlgorithmName(this.pkcs1.getAlgorithm());
            for (AlgAndLength algLength : listOfAlgAndLength) {
                if (algLength.getAlgID().getValue().equalsIgnoreCase(varSetedAlgorithmOID)) {
                    algAndLength = algLength;
                    SignerAlgorithmEnum varSignerAlgorithmEnum = SignerAlgorithmEnum.valueOf(this.pkcs1.getAlgorithm());
                    String varOIDAlgorithmHash = varSignerAlgorithmEnum.getOIDAlgorithmHash();
                    ObjectIdentifier varObjectIdentifier = signaturePolicy.getSignPolicyHashAlg().getAlgorithm();
                    varObjectIdentifier.setValue(varOIDAlgorithmHash);
                    AlgorithmIdentifier varAlgorithmIdentifier = signaturePolicy.getSignPolicyHashAlg();
                    varAlgorithmIdentifier.setAlgorithm(varObjectIdentifier);
                    signaturePolicy.setSignPolicyHashAlg(varAlgorithmIdentifier);
                }
            }
        } else {
            algAndLength = listOfAlgAndLength.get(0);
        }
        if (algAndLength == null) {
            throw new SignerException(cadesMessagesBundle.getString("error.no.algorithm.policy"));
        }
        logger.info(cadesMessagesBundle.getString("info.algorithm.id", algAndLength.getAlgID().getValue()));
        logger.info(cadesMessagesBundle.getString("info.algorithm.name", AlgorithmNames.getAlgorithmNameByOID(algAndLength.getAlgID().getValue())));
        logger.info(cadesMessagesBundle.getString("info.algorithm.policy.default", AlgorithmNames.getOIDByAlgorithmName(getAlgorithm())));
        logger.info(cadesMessagesBundle.getString("info.min.key.length", algAndLength.getMinKeyLength()));
        // Recupera o tamanho minimo da chave para validacao
        logger.info(cadesMessagesBundle.getString("info.validating.key.length"));
        int keyLegth = ((RSAKey) certificate.getPublicKey()).getModulus().bitLength();
        if (keyLegth < algAndLength.getMinKeyLength()) {
            throw new SignerException(cadesMessagesBundle.getString("error.min.key.length", algAndLength.getMinKeyLength().toString(), keyLegth));
        }
        AttributeFactory attributeFactory = AttributeFactory.getInstance();
        // Consulta e adiciona os atributos assinados
        ASN1EncodableVector signedAttributes = new ASN1EncodableVector();
        logger.info(cadesMessagesBundle.getString("info.signed.attribute"));
        if (signaturePolicy.getSignPolicyInfo().getSignatureValidationPolicy().getCommonRules().getSignerAndVeriferRules().getSignerRules().getMandatedSignedAttr().getObjectIdentifiers() != null) {
            for (ObjectIdentifier objectIdentifier : signaturePolicy.getSignPolicyInfo().getSignatureValidationPolicy().getCommonRules().getSignerAndVeriferRules().getSignerRules().getMandatedSignedAttr().getObjectIdentifiers()) {
                SignedOrUnsignedAttribute signedOrUnsignedAttribute = attributeFactory.factory(objectIdentifier.getValue());
                signedOrUnsignedAttribute.initialize(this.pkcs1.getPrivateKey(), certificateChain, content, signaturePolicy, this.hash);
                signedAttributes.add(signedOrUnsignedAttribute.getValue());
            }
        }
        // Monta a tabela de atributos assinados
        AttributeTable signedAttributesTable = new AttributeTable(signedAttributes);
        // Create the table table generator that will added to the Signer
        // builder
        CMSAttributeTableGenerator signedAttributeGenerator = new DefaultSignedAttributeTableGenerator(signedAttributesTable);
        // Recupera o(s) certificado(s) de confianca para validacao
        Collection<X509Certificate> trustedCAs = new HashSet<X509Certificate>();
        Collection<CertificateTrustPoint> ctp = signaturePolicy.getSignPolicyInfo().getSignatureValidationPolicy().getCommonRules().getSigningCertTrustCondition().getSignerTrustTrees().getCertificateTrustPoints();
        for (CertificateTrustPoint certificateTrustPoint : ctp) {
            logger.info(cadesMessagesBundle.getString("info.trust.point", certificateTrustPoint.getTrustpoint().getSubjectDN().toString()));
            trustedCAs.add(certificateTrustPoint.getTrustpoint());
        }
        // Efetua a validacao das cadeias do certificado baseado na politica
        Collection<X509Certificate> certificateChainTrusted = new HashSet<X509Certificate>();
        for (Certificate certCA : certificateChain) {
            certificateChainTrusted.add((X509Certificate) certCA);
        }
        X509Certificate rootOfCertificate = null;
        for (X509Certificate tcac : certificateChainTrusted) {
            logger.info(tcac.getIssuerDN().toString());
            if (CAManager.getInstance().isRootCA(tcac)) {
                rootOfCertificate = tcac;
            }
        }
        if (trustedCAs.contains(rootOfCertificate)) {
            logger.info(cadesMessagesBundle.getString("info.trust.in.point", rootOfCertificate.getSubjectDN()));
        } else {
            // Não encontrou na política, verificará nas cadeias do
            // componente chain-icp-brasil provavelmente certificado de
            // homologação.
            logger.warn(cadesMessagesBundle.getString("info.trust.poin.homolog"));
            CAManager.getInstance().validateRootCAs(certificateChainTrusted, certificate);
        }
        // validade da politica
        logger.info(cadesMessagesBundle.getString("info.policy.valid.period"));
        PolicyValidator pv = new PolicyValidator(this.signaturePolicy, this.policyName);
        pv.validate();
        // Realiza a assinatura do conteudo
        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
        gen.addCertificates(this.generatedCertStore(certStore));
        String algorithmOID = algAndLength.getAlgID().getValue();
        logger.info(cadesMessagesBundle.getString("info.algorithm.id", algorithmOID));
        SignerInfoGenerator signerInfoGenerator = new JcaSimpleSignerInfoGeneratorBuilder().setSignedAttributeGenerator(signedAttributeGenerator).setUnsignedAttributeGenerator(null).build(AlgorithmNames.getAlgorithmNameByOID(algorithmOID), this.pkcs1.getPrivateKey(), this.certificate);
        gen.addSignerInfoGenerator(signerInfoGenerator);
        CMSTypedData cmsTypedData;
        // para assinatura do hash, content nulo
        if (content == null) {
            cmsTypedData = new CMSAbsentContent();
        } else {
            cmsTypedData = new CMSProcessableByteArray(content);
        }
        // Efetua a assinatura digital do conteúdo
        CMSSignedData cmsSignedData = gen.generate(cmsTypedData, this.attached);
        setAttached(false);
        // Consulta e adiciona os atributos não assinados//
        ASN1EncodableVector unsignedAttributes = new ASN1EncodableVector();
        logger.info(cadesMessagesBundle.getString("info.unsigned.attribute"));
        Collection<SignerInformation> vNewSigners = cmsSignedData.getSignerInfos().getSigners();
        Iterator<SignerInformation> it = vNewSigners.iterator();
        SignerInformation oSi = it.next();
        if (signaturePolicy.getSignPolicyInfo().getSignatureValidationPolicy().getCommonRules().getSignerAndVeriferRules().getSignerRules().getMandatedUnsignedAttr().getObjectIdentifiers() != null) {
            for (ObjectIdentifier objectIdentifier : signaturePolicy.getSignPolicyInfo().getSignatureValidationPolicy().getCommonRules().getSignerAndVeriferRules().getSignerRules().getMandatedUnsignedAttr().getObjectIdentifiers()) {
                SignedOrUnsignedAttribute signedOrUnsignedAttribute = attributeFactory.factory(objectIdentifier.getValue());
                if (signedOrUnsignedAttribute.getOID().equalsIgnoreCase(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken.getId())) {
                    signedOrUnsignedAttribute.initialize(this.pkcs1.getPrivateKey(), this.certificateChainTimeStamp, oSi.getSignature(), signaturePolicy, this.hash);
                }
                if (// EscTimeStamp
                signedOrUnsignedAttribute.getOID().equalsIgnoreCase("1.2.840.113549.1.9.16.2.25")) {
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    outputStream.write(oSi.getSignature());
                    AttributeTable varUnsignedAttributes = oSi.getUnsignedAttributes();
                    Attribute varAttribute = varUnsignedAttributes.get(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken.getId()));
                    outputStream.write(varAttribute.getAttrType().getEncoded());
                    outputStream.write(varAttribute.getAttrValues().getEncoded());
                    varAttribute = varUnsignedAttributes.get(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.id_aa_ets_certificateRefs.getId()));
                    outputStream.write(varAttribute.getAttrType().getEncoded());
                    outputStream.write(varAttribute.getAttrValues().getEncoded());
                    varAttribute = varUnsignedAttributes.get(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.id_aa_ets_revocationRefs.getId()));
                    outputStream.write(varAttribute.getAttrType().getEncoded());
                    outputStream.write(varAttribute.getAttrValues().getEncoded());
                    escTimeStampContent = outputStream.toByteArray();
                    signedOrUnsignedAttribute.initialize(this.pkcs1.getPrivateKey(), this.certificateChainTimeStamp, escTimeStampContent, signaturePolicy, this.hash);
                } else {
                    signedOrUnsignedAttribute.initialize(this.pkcs1.getPrivateKey(), certificateChain, oSi.getSignature(), signaturePolicy, this.hash);
                }
                unsignedAttributes.add(signedOrUnsignedAttribute.getValue());
                AttributeTable unsignedAttributesTable = new AttributeTable(unsignedAttributes);
                vNewSigners.remove(oSi);
                oSi = SignerInformation.replaceUnsignedAttributes(oSi, unsignedAttributesTable);
                vNewSigners.add(oSi);
            }
        }
        // TODO Estudar este método de contra-assinatura posteriormente
        if (previewSignature != null && previewSignature.length > 0) {
            vNewSigners.addAll(cmsPreviewSignedData.getSignerInfos().getSigners());
        }
        SignerInformationStore oNewSignerInformationStore = new SignerInformationStore(vNewSigners);
        CMSSignedData oSignedData = cmsSignedData;
        cmsSignedData = CMSSignedData.replaceSigners(oSignedData, oNewSignerInformationStore);
        byte[] result = cmsSignedData.getEncoded();
        logger.info(cadesMessagesBundle.getString("info.signature.ok"));
        return result;
    } catch (CMSException | IOException | OperatorCreationException | CertificateEncodingException ex) {
        throw new SignerException(ex);
    }
}
Also used : CMSSignedDataGenerator(org.bouncycastle.cms.CMSSignedDataGenerator) DefaultSignedAttributeTableGenerator(org.bouncycastle.cms.DefaultSignedAttributeTableGenerator) Attribute(org.bouncycastle.asn1.cms.Attribute) SignedOrUnsignedAttribute(org.demoiselle.signer.policy.impl.cades.pkcs7.attribute.SignedOrUnsignedAttribute) ArrayList(java.util.ArrayList) SignedOrUnsignedAttribute(org.demoiselle.signer.policy.impl.cades.pkcs7.attribute.SignedOrUnsignedAttribute) AttributeTable(org.bouncycastle.asn1.cms.AttributeTable) CertificateManager(org.demoiselle.signer.core.CertificateManager) SignerInformation(org.bouncycastle.cms.SignerInformation) AlgorithmIdentifier(org.demoiselle.signer.policy.engine.asn1.etsi.AlgorithmIdentifier) CertificateTrustPoint(org.demoiselle.signer.policy.engine.asn1.etsi.CertificateTrustPoint) SignerInformationStore(org.bouncycastle.cms.SignerInformationStore) CMSAttributeTableGenerator(org.bouncycastle.cms.CMSAttributeTableGenerator) ASN1EncodableVector(org.bouncycastle.asn1.ASN1EncodableVector) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) JcaSimpleSignerInfoGeneratorBuilder(org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder) BouncyCastleProvider(org.bouncycastle.jce.provider.BouncyCastleProvider) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) ObjectIdentifier(org.demoiselle.signer.policy.engine.asn1.etsi.ObjectIdentifier) HashSet(java.util.HashSet) CMSProcessableByteArray(org.bouncycastle.cms.CMSProcessableByteArray) CMSTypedData(org.bouncycastle.cms.CMSTypedData) SignerAlgorithmEnum(org.demoiselle.signer.policy.impl.cades.SignerAlgorithmEnum) CMSAbsentContent(org.bouncycastle.cms.CMSAbsentContent) AlgAndLength(org.demoiselle.signer.policy.engine.asn1.etsi.AlgAndLength) AttributeFactory(org.demoiselle.signer.policy.impl.cades.pkcs7.attribute.factory.AttributeFactory) CertificateEncodingException(java.security.cert.CertificateEncodingException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) CMSSignedData(org.bouncycastle.cms.CMSSignedData) X509Certificate(java.security.cert.X509Certificate) CertificateTrustPoint(org.demoiselle.signer.policy.engine.asn1.etsi.CertificateTrustPoint) PolicyValidator(org.demoiselle.signer.policy.engine.asn1.icpb.v2.PolicyValidator) SignerInfoGenerator(org.bouncycastle.cms.SignerInfoGenerator) SignerException(org.demoiselle.signer.policy.impl.cades.SignerException) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate) CMSException(org.bouncycastle.cms.CMSException)

Aggregations

SignerInformation (org.bouncycastle.cms.SignerInformation)32 SignerInformationStore (org.bouncycastle.cms.SignerInformationStore)21 CMSSignedData (org.bouncycastle.cms.CMSSignedData)19 X509Certificate (java.security.cert.X509Certificate)17 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)13 JcaSimpleSignerInfoVerifierBuilder (org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder)13 CMSException (org.bouncycastle.cms.CMSException)10 JcaX509CertificateConverter (org.bouncycastle.cert.jcajce.JcaX509CertificateConverter)8 CertificateException (java.security.cert.CertificateException)7 Attribute (org.bouncycastle.asn1.cms.Attribute)7 AttributeTable (org.bouncycastle.asn1.cms.AttributeTable)7 CMSProcessableByteArray (org.bouncycastle.cms.CMSProcessableByteArray)7 OperatorCreationException (org.bouncycastle.operator.OperatorCreationException)7 IOException (java.io.IOException)6 ArrayList (java.util.ArrayList)6 Collection (java.util.Collection)6 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)6 FileInputStream (java.io.FileInputStream)4 CertStore (java.security.cert.CertStore)4 Date (java.util.Date)4