Search in sources :

Example 46 with Attributes

use of org.bouncycastle.asn1.cms.Attributes in project xipki by xipki.

the class ExtensionsChecker method checkExtensionSubjectDirAttrs.

// method checkExtensionInhibitAnyPolicy
private void checkExtensionSubjectDirAttrs(StringBuilder failureMsg, byte[] extensionValue, Extensions requestedExtensions, ExtensionControl extControl) {
    SubjectDirectoryAttributesControl conf = certProfile.getSubjectDirAttrsControl();
    if (conf == null) {
        failureMsg.append("extension is present but not expected; ");
        return;
    }
    ASN1Encodable extInRequest = null;
    if (requestedExtensions != null) {
        extInRequest = requestedExtensions.getExtensionParsedValue(Extension.subjectDirectoryAttributes);
    }
    if (extInRequest == null) {
        failureMsg.append("extension is present but not expected; ");
        return;
    }
    SubjectDirectoryAttributes requested = SubjectDirectoryAttributes.getInstance(extInRequest);
    Vector<?> reqSubDirAttrs = requested.getAttributes();
    ASN1GeneralizedTime expDateOfBirth = null;
    String expPlaceOfBirth = null;
    String expGender = null;
    Set<String> expCountryOfCitizenshipList = new HashSet<>();
    Set<String> expCountryOfResidenceList = new HashSet<>();
    Map<ASN1ObjectIdentifier, Set<ASN1Encodable>> expOtherAttrs = new HashMap<>();
    final int expN = reqSubDirAttrs.size();
    for (int i = 0; i < expN; i++) {
        Attribute attr = Attribute.getInstance(reqSubDirAttrs.get(i));
        ASN1ObjectIdentifier attrType = attr.getAttrType();
        ASN1Encodable attrVal = attr.getAttributeValues()[0];
        if (ObjectIdentifiers.DN_DATE_OF_BIRTH.equals(attrType)) {
            expDateOfBirth = ASN1GeneralizedTime.getInstance(attrVal);
        } else if (ObjectIdentifiers.DN_PLACE_OF_BIRTH.equals(attrType)) {
            expPlaceOfBirth = DirectoryString.getInstance(attrVal).getString();
        } else if (ObjectIdentifiers.DN_GENDER.equals(attrType)) {
            expGender = DERPrintableString.getInstance(attrVal).getString();
        } else if (ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP.equals(attrType)) {
            String country = DERPrintableString.getInstance(attrVal).getString();
            expCountryOfCitizenshipList.add(country);
        } else if (ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE.equals(attrType)) {
            String country = DERPrintableString.getInstance(attrVal).getString();
            expCountryOfResidenceList.add(country);
        } else {
            Set<ASN1Encodable> otherAttrVals = expOtherAttrs.get(attrType);
            if (otherAttrVals == null) {
                otherAttrVals = new HashSet<>();
                expOtherAttrs.put(attrType, otherAttrVals);
            }
            otherAttrVals.add(attrVal);
        }
    }
    SubjectDirectoryAttributes ext = SubjectDirectoryAttributes.getInstance(extensionValue);
    Vector<?> subDirAttrs = ext.getAttributes();
    ASN1GeneralizedTime dateOfBirth = null;
    String placeOfBirth = null;
    String gender = null;
    Set<String> countryOfCitizenshipList = new HashSet<>();
    Set<String> countryOfResidenceList = new HashSet<>();
    Map<ASN1ObjectIdentifier, Set<ASN1Encodable>> otherAttrs = new HashMap<>();
    List<ASN1ObjectIdentifier> attrTypes = new LinkedList<>(conf.getTypes());
    final int n = subDirAttrs.size();
    for (int i = 0; i < n; i++) {
        Attribute attr = Attribute.getInstance(subDirAttrs.get(i));
        ASN1ObjectIdentifier attrType = attr.getAttrType();
        if (!attrTypes.contains(attrType)) {
            failureMsg.append("attribute of type " + attrType.getId()).append(" is present but not expected; ");
            continue;
        }
        ASN1Encodable[] attrs = attr.getAttributeValues();
        if (attrs.length != 1) {
            failureMsg.append("attribute of type ").append(attrType.getId()).append(" does not single-value value: ").append(attrs.length).append("; ");
            continue;
        }
        ASN1Encodable attrVal = attrs[0];
        if (ObjectIdentifiers.DN_DATE_OF_BIRTH.equals(attrType)) {
            dateOfBirth = ASN1GeneralizedTime.getInstance(attrVal);
        } else if (ObjectIdentifiers.DN_PLACE_OF_BIRTH.equals(attrType)) {
            placeOfBirth = DirectoryString.getInstance(attrVal).getString();
        } else if (ObjectIdentifiers.DN_GENDER.equals(attrType)) {
            gender = DERPrintableString.getInstance(attrVal).getString();
        } else if (ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP.equals(attrType)) {
            String country = DERPrintableString.getInstance(attrVal).getString();
            countryOfCitizenshipList.add(country);
        } else if (ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE.equals(attrType)) {
            String country = DERPrintableString.getInstance(attrVal).getString();
            countryOfResidenceList.add(country);
        } else {
            Set<ASN1Encodable> otherAttrVals = otherAttrs.get(attrType);
            if (otherAttrVals == null) {
                otherAttrVals = new HashSet<>();
                otherAttrs.put(attrType, otherAttrVals);
            }
            otherAttrVals.add(attrVal);
        }
    }
    if (dateOfBirth != null) {
        attrTypes.remove(ObjectIdentifiers.DN_DATE_OF_BIRTH);
    }
    if (placeOfBirth != null) {
        attrTypes.remove(ObjectIdentifiers.DN_PLACE_OF_BIRTH);
    }
    if (gender != null) {
        attrTypes.remove(ObjectIdentifiers.DN_GENDER);
    }
    if (!countryOfCitizenshipList.isEmpty()) {
        attrTypes.remove(ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP);
    }
    if (!countryOfResidenceList.isEmpty()) {
        attrTypes.remove(ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE);
    }
    attrTypes.removeAll(otherAttrs.keySet());
    if (!attrTypes.isEmpty()) {
        List<String> attrTypeTexts = new LinkedList<>();
        for (ASN1ObjectIdentifier oid : attrTypes) {
            attrTypeTexts.add(oid.getId());
        }
        failureMsg.append("required attributes of types ").append(attrTypeTexts).append(" are not present; ");
    }
    if (dateOfBirth != null) {
        String timeStirng = dateOfBirth.getTimeString();
        if (!SubjectDnSpec.PATTERN_DATE_OF_BIRTH.matcher(timeStirng).matches()) {
            failureMsg.append("invalid dateOfBirth: " + timeStirng + "; ");
        }
        String exp = (expDateOfBirth == null) ? null : expDateOfBirth.getTimeString();
        if (!timeStirng.equalsIgnoreCase(exp)) {
            addViolation(failureMsg, "dateOfBirth", timeStirng, exp);
        }
    }
    if (gender != null) {
        if (!(gender.equalsIgnoreCase("F") || gender.equalsIgnoreCase("M"))) {
            failureMsg.append("invalid gender: ").append(gender).append("; ");
        }
        if (!gender.equalsIgnoreCase(expGender)) {
            addViolation(failureMsg, "gender", gender, expGender);
        }
    }
    if (placeOfBirth != null) {
        if (!placeOfBirth.equals(expPlaceOfBirth)) {
            addViolation(failureMsg, "placeOfBirth", placeOfBirth, expPlaceOfBirth);
        }
    }
    if (!countryOfCitizenshipList.isEmpty()) {
        Set<String> diffs = strInBnotInA(expCountryOfCitizenshipList, countryOfCitizenshipList);
        if (CollectionUtil.isNonEmpty(diffs)) {
            failureMsg.append("countryOfCitizenship ").append(diffs.toString()).append(" are present but not expected; ");
        }
        diffs = strInBnotInA(countryOfCitizenshipList, expCountryOfCitizenshipList);
        if (CollectionUtil.isNonEmpty(diffs)) {
            failureMsg.append("countryOfCitizenship ").append(diffs.toString()).append(" are absent but are required; ");
        }
    }
    if (!countryOfResidenceList.isEmpty()) {
        Set<String> diffs = strInBnotInA(expCountryOfResidenceList, countryOfResidenceList);
        if (CollectionUtil.isNonEmpty(diffs)) {
            failureMsg.append("countryOfResidence ").append(diffs.toString()).append(" are present but not expected; ");
        }
        diffs = strInBnotInA(countryOfResidenceList, expCountryOfResidenceList);
        if (CollectionUtil.isNonEmpty(diffs)) {
            failureMsg.append("countryOfResidence ").append(diffs.toString()).append(" are absent but are required; ");
        }
    }
    if (!otherAttrs.isEmpty()) {
        for (ASN1ObjectIdentifier attrType : otherAttrs.keySet()) {
            Set<ASN1Encodable> expAttrValues = expOtherAttrs.get(attrType);
            if (expAttrValues == null) {
                failureMsg.append("attribute of type ").append(attrType.getId()).append(" is present but not requested; ");
                continue;
            }
            Set<ASN1Encodable> attrValues = otherAttrs.get(attrType);
            if (!attrValues.equals(expAttrValues)) {
                failureMsg.append("attribute of type ").append(attrType.getId()).append(" differs from the requested one; ");
                continue;
            }
        }
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) Attribute(org.bouncycastle.asn1.x509.Attribute) SubjectDirectoryAttributes(org.bouncycastle.asn1.x509.SubjectDirectoryAttributes) ASN1GeneralizedTime(org.bouncycastle.asn1.ASN1GeneralizedTime) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DERBMPString(org.bouncycastle.asn1.DERBMPString) DERPrintableString(org.bouncycastle.asn1.DERPrintableString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) ASN1String(org.bouncycastle.asn1.ASN1String) DirectoryString(org.bouncycastle.asn1.x500.DirectoryString) QaDirectoryString(org.xipki.ca.qa.internal.QaDirectoryString) DEROctetString(org.bouncycastle.asn1.DEROctetString) DERIA5String(org.bouncycastle.asn1.DERIA5String) DERT61String(org.bouncycastle.asn1.DERT61String) CRLDistPoint(org.bouncycastle.asn1.x509.CRLDistPoint) DistributionPoint(org.bouncycastle.asn1.x509.DistributionPoint) LinkedList(java.util.LinkedList) SubjectDirectoryAttributesControl(org.xipki.ca.api.profile.x509.SubjectDirectoryAttributesControl) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) HashSet(java.util.HashSet)

Example 47 with Attributes

use of org.bouncycastle.asn1.cms.Attributes in project xipki by xipki.

the class ExtensionsChecker method getRequestedSubjectAltNames.

// method checkExtensionSubjectAltName
private GeneralName[] getRequestedSubjectAltNames(X500Name requestedSubject, Extensions requestedExtensions) throws CertprofileException, BadCertTemplateException {
    ASN1Encodable extValue = (requestedExtensions == null) ? null : requestedExtensions.getExtensionParsedValue(Extension.subjectAlternativeName);
    Map<ASN1ObjectIdentifier, GeneralNameTag> subjectToSubjectAltNameModes = certProfile.getSubjectToSubjectAltNameModes();
    if (extValue == null && subjectToSubjectAltNameModes == null) {
        return null;
    }
    GeneralNames reqNames = (extValue == null) ? null : GeneralNames.getInstance(extValue);
    Set<GeneralNameMode> subjectAltNameModes = certProfile.getSubjectAltNameModes();
    if (subjectAltNameModes == null && subjectToSubjectAltNameModes == null) {
        return (reqNames == null) ? null : reqNames.getNames();
    }
    List<GeneralName> grantedNames = new LinkedList<>();
    // copy the required attributes of Subject
    if (subjectToSubjectAltNameModes != null) {
        X500Name grantedSubject;
        try {
            grantedSubject = certProfile.getSubject(requestedSubject).getGrantedSubject();
        } catch (CertprofileException | BadCertTemplateException ex) {
            if (certProfile.getSpecialCertprofileBehavior() == null) {
                throw ex;
            }
            LogUtil.warn(LOG, ex, "could not derive granted subject from requested subject");
            grantedSubject = requestedSubject;
        }
        for (ASN1ObjectIdentifier attrType : subjectToSubjectAltNameModes.keySet()) {
            GeneralNameTag tag = subjectToSubjectAltNameModes.get(attrType);
            RDN[] rdns = grantedSubject.getRDNs(attrType);
            if (rdns == null) {
                rdns = requestedSubject.getRDNs(attrType);
            }
            if (rdns == null) {
                continue;
            }
            for (RDN rdn : rdns) {
                String rdnValue = X509Util.rdnValueToString(rdn.getFirst().getValue());
                switch(tag) {
                    case rfc822Name:
                    case dNSName:
                    case uniformResourceIdentifier:
                    case iPAddress:
                    case directoryName:
                    case registeredID:
                        grantedNames.add(new GeneralName(tag.getTag(), rdnValue));
                        break;
                    default:
                        throw new RuntimeException("should not reach here, unknown GeneralName tag " + tag);
                }
            // end switch (tag)
            }
        }
    }
    // copy the requested SubjectAltName entries
    if (reqNames != null) {
        GeneralName[] reqL = reqNames.getNames();
        for (int i = 0; i < reqL.length; i++) {
            grantedNames.add(reqL[i]);
        }
    }
    return grantedNames.isEmpty() ? null : grantedNames.toArray(new GeneralName[0]);
}
Also used : GeneralNameMode(org.xipki.ca.api.profile.GeneralNameMode) GeneralNameTag(org.xipki.ca.api.profile.GeneralNameTag) X500Name(org.bouncycastle.asn1.x500.X500Name) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DERBMPString(org.bouncycastle.asn1.DERBMPString) DERPrintableString(org.bouncycastle.asn1.DERPrintableString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) ASN1String(org.bouncycastle.asn1.ASN1String) DirectoryString(org.bouncycastle.asn1.x500.DirectoryString) QaDirectoryString(org.xipki.ca.qa.internal.QaDirectoryString) DEROctetString(org.bouncycastle.asn1.DEROctetString) DERIA5String(org.bouncycastle.asn1.DERIA5String) DERT61String(org.bouncycastle.asn1.DERT61String) LinkedList(java.util.LinkedList) CRLDistPoint(org.bouncycastle.asn1.x509.CRLDistPoint) DistributionPoint(org.bouncycastle.asn1.x509.DistributionPoint) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) CertprofileException(org.xipki.ca.api.profile.CertprofileException) BadCertTemplateException(org.xipki.ca.api.BadCertTemplateException) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) GeneralName(org.bouncycastle.asn1.x509.GeneralName) RDN(org.bouncycastle.asn1.x500.RDN) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Example 48 with Attributes

use of org.bouncycastle.asn1.cms.Attributes in project xipki by xipki.

the class ScepUtil method generateRequest.

public static PKCS10CertificationRequest generateRequest(PrivateKey privatekey, SubjectPublicKeyInfo subjectPublicKeyInfo, X500Name subjectDn, Map<ASN1ObjectIdentifier, ASN1Encodable> attributes) throws OperatorCreationException {
    requireNonNull("privatekey", privatekey);
    requireNonNull("subjectPublicKeyInfo", subjectPublicKeyInfo);
    requireNonNull("subjectDn", subjectDn);
    PKCS10CertificationRequestBuilder csrBuilder = new PKCS10CertificationRequestBuilder(subjectDn, subjectPublicKeyInfo);
    if (attributes != null) {
        for (ASN1ObjectIdentifier attrType : attributes.keySet()) {
            csrBuilder.addAttribute(attrType, attributes.get(attrType));
        }
    }
    ContentSigner contentSigner = new JcaContentSignerBuilder(getSignatureAlgorithm(privatekey, ScepHashAlgo.SHA1)).build(privatekey);
    return csrBuilder.build(contentSigner);
}
Also used : JcaContentSignerBuilder(org.bouncycastle.operator.jcajce.JcaContentSignerBuilder) ContentSigner(org.bouncycastle.operator.ContentSigner) PKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Example 49 with Attributes

use of org.bouncycastle.asn1.cms.Attributes 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 50 with Attributes

use of org.bouncycastle.asn1.cms.Attributes 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)

Aggregations

ASN1EncodableVector (org.bouncycastle.asn1.ASN1EncodableVector)20 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)19 ASN1OctetString (org.bouncycastle.asn1.ASN1OctetString)16 ASN1Encodable (org.bouncycastle.asn1.ASN1Encodable)15 DEROctetString (org.bouncycastle.asn1.DEROctetString)13 X509Certificate (java.security.cert.X509Certificate)12 IOException (java.io.IOException)10 Date (java.util.Date)10 ASN1Sequence (org.bouncycastle.asn1.ASN1Sequence)10 DERSequence (org.bouncycastle.asn1.DERSequence)9 DERIA5String (org.bouncycastle.asn1.DERIA5String)8 DERSet (org.bouncycastle.asn1.DERSet)8 Attribute (org.bouncycastle.asn1.cms.Attribute)8 AttributeTable (org.bouncycastle.asn1.cms.AttributeTable)8 GeneralNames (org.bouncycastle.asn1.x509.GeneralNames)8 ByteArrayInputStream (java.io.ByteArrayInputStream)7 BigInteger (java.math.BigInteger)7 KeyStore (java.security.KeyStore)7 DERPrintableString (org.bouncycastle.asn1.DERPrintableString)7 DERTaggedObject (org.bouncycastle.asn1.DERTaggedObject)7