Andreas F.
Andreas F.

Reputation: 11

CMS/CMC message with null signature and no-signature signature

I'm trying to create a CMC message wrapped inside CMS to feed MS ADCS service with a certificate request. We're trying to fulfill the specification (WCCE - 2.2.2.6.5 Null Signature and WCCE - 3.1.1.4.3.1.3 New Certificate Request Using CMS and CMC Request Formats) from Microsoft.

I successfully null signed the inner CMC message (eContent).

If I read the spec, I should be able to "sign" the outer CMS message with a so called no-signature. This is specified in RFC-2797 and RFC-5272.

My code looks like so:

private static final AlgorithmIdentifier SHA256_ALG_ID =
    new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE);

/**
 * @param entry Contains all informations required for a CertificationRequest in CMC format.
 */
private void buildCMSTaggedRequest(EnrollCertsRequestEntry entry) {
    try {
        // OIDs
        ASN1ObjectIdentifier idCctPkiData = CMCObjectIdentifiers.id_cct_PKIData;
        AlgorithmIdentifier noSignatureAlgId =
            new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.3.6.1.5.5.7.6.2"), DERNull.INSTANCE);

        // Create a no signed cmc request based on PKCS#10 Request Format
        org.bouncycastle.asn1.cmc.CertificationRequest certReq = parseRequestInCSRWithNullSignature(entry);

        // Create a TaggedCertificationRequest for CMC
        BodyPartID bodyPartID = new BodyPartID(1L);
        TaggedCertificationRequest req = new TaggedCertificationRequest(bodyPartID, certReq);
        TaggedRequest taggedRequest = new TaggedRequest(req);

        // Create the PKIData structure with the request
        TaggedAttribute[] taggedAttributes = new TaggedAttribute[0];
        TaggedRequest[] taggedRequests = new TaggedRequest[] {taggedRequest};
        TaggedContentInfo[] taggedContentInfos = new TaggedContentInfo[0];
        OtherMsg[] otherMsgs = new OtherMsg[0];

        // no CMS content or other messages
        PKIData pkiData = new PKIData(taggedAttributes, taggedRequests, taggedContentInfos, otherMsgs);

        // Create the CMS SignedData with PKIData as a CMS processable object
        byte[] pkiDataBytes = pkiData.getEncoded(ASN1Encoding.DER);
        org.bouncycastle.cms.CMSTypedData cmsData =
            new org.bouncycastle.cms.CMSProcessableByteArray(idCctPkiData, pkiDataBytes);

        // ContentSigner
        ContentSigner contentSigner = new ContentSigner() {
            private final ByteArrayOutputStream bos = new ByteArrayOutputStream();

            @Override
            public AlgorithmIdentifier getAlgorithmIdentifier() {
                return noSignatureAlgId; // noSignature
            }

            @Override
            public OutputStream getOutputStream() {
                return bos;
            }

            @Override
            public byte[] getSignature() {
                return computeHash(pkiDataBytes, "SHA-256");
            }
        };

        // CMSSignedDataGenerator
        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
        gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
            new JcaDigestCalculatorProviderBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME).build())
                                       .setContentDigest(SHA256_ALG_ID)
                                       .setDirectSignature(true)
                                       .build(contentSigner, new byte[0]));
        org.bouncycastle.cms.CMSSignedData cmsSignedData = gen.generate(cmsData, true);
        saveToFileWithDerFormat(cmsSignedData);
        saveToFileWithPemFormat(cmsSignedData);
    } catch (OperationException | OperatorCreationException | CMSException | IOException e) {
        log.error("An error occurred: '{}'", e.getMessage());
    }
}

I tried to check my generated messages with certutil. I got a "null-signature verified" for inner messages but certutil give me:

The request is not supported. 0x80070032 (WIN32: 50 ERROR_NOT_SUPPORTED)

The generated ASN.1 structure is:

SEQUENCE (2 elem)
  OBJECT IDENTIFIER 1.2.840.113549.1.7.2 signedData (PKCS #7)
  [0] (1 elem)
    SEQUENCE (4 elem)
      INTEGER 3
      SET (1 elem)
        SEQUENCE (1 elem)
          OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 (NIST Algorithm)
      SEQUENCE (2 elem)
        OBJECT IDENTIFIER 1.3.6.1.5.5.7.12.2 pkiData (PKIX CMC Content Types)
        [0] (1 elem)
          OCTET STRING (783 byte) <redacted>
            SEQUENCE (4 elem)
              SEQUENCE (0 elem)
              SEQUENCE (1 elem)
                [0] (2 elem)
                  INTEGER 1
                  SEQUENCE (3 elem)
                    SEQUENCE (4 elem)
                      INTEGER 0
                      SEQUENCE (5 elem)
                        SET (1 elem)
                          SEQUENCE (2 elem)
                            OBJECT IDENTIFIER 2.5.4.6 countryName (X.520 DN component)
                            PrintableString DE
                        SET (1 elem)
                          SEQUENCE (2 elem)
                            OBJECT IDENTIFIER 2.5.4.10 organizationName (X.520 DN component)
                            PrintableString Foo
                        SET (1 elem)
                          SEQUENCE (2 elem)
                            OBJECT IDENTIFIER 2.5.4.11 organizationalUnitName (X.520 DN component)
                            PrintableString Bar
                        SET (1 elem)
                          SEQUENCE (2 elem)
                            OBJECT IDENTIFIER 2.5.4.3 commonName (X.520 DN component)
                            PrintableString baz.foo
                        SET (1 elem)
                          SEQUENCE (2 elem)
                            OBJECT IDENTIFIER 1.2.840.113549.1.9.1 emailAddress (PKCS #9. Deprecated, use an altName extension instead)
                            IA5String <redacted>
                      SEQUENCE (2 elem)
                        SEQUENCE (2 elem)
                          OBJECT IDENTIFIER 1.2.840.113549.1.1.1 rsaEncryption (PKCS #1)
                          NULL
                        BIT STRING (4208 bit) 001100001000001000000010000010100000001010000010000000100000000100000…
                          SEQUENCE (2 elem)
                            INTEGER (4096 bit) 635009886005968988895378575848641762416670566327845526625145124343210…
                            INTEGER 65537
                      [0] (0 elem)
                    SEQUENCE (1 elem)
                      OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 (NIST Algorithm)
                    BIT STRING (256 bit) 1111101000100010000101111010111001111011011010011110011101000001101111…
              SEQUENCE (0 elem)
              SEQUENCE (0 elem)
      SET (1 elem)
        SEQUENCE (5 elem)
          INTEGER 3
          [0] (0 byte)
          SEQUENCE (1 elem)
            OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 (NIST Algorithm)
          SEQUENCE (2 elem)
            OBJECT IDENTIFIER 1.3.6.1.5.5.7.6.2 noSignature (PKIX algorithm)
            NULL
          OCTET STRING (32 byte) D50D3A75BBFFBE98FE767F30F4D1C7E71F51F26BA1CF8A2A0F012D557A68854D

What I'm doing wrong?

Upvotes: 0

Views: 46

Answers (0)

Related Questions