Reputation: 11
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