Hi,
Thanks for all the help. I modified the code based on your comments.
Basically, I am trying to verify a CMS data signed by a C# program. So I have
the base 64 decoded CSM data stored as nBytes a BYTE array.
I have to verify the data(nBytes) using the DSA params and public key which is
hard coded in the code as const char arrays(uLicenseCheckG,
uLicenseCheckP, uLicenseCheckQ and uLicenseCheckY).
I tried to verify even using the CMS_NO_CONTENT_VERIFY flag. CMS_verify() fails
with error "signer certificate not found".
I digged in to the code and found that CMS_Verify() tries to copy the st(stack
of x509 certs) to cms and fails? I am copying the skid value from the
cms and creating the x509Cert using that so they match. I have notices that the
x509Cert->skid is becoming NULL after the call to CMS_verify().
Is there anything wrong with the above x509 cert created above with the public
key and DSA params and skid. Am I missing something?
What else do I need to verify correctly?
Please find the modified code below.
-Ujwal
//COPY the DSA params and public keys from const char arrays into DSA structure
DSA *dsaParams= DSA_new();
dsaParams->g = BN_new();
dsaParams->p = BN_new();
dsaParams->q = BN_new();
dsaParams->pub_key = BN_new();
BN_bin2bn((const unsigned char *)uLicenseCheckG, sizeof(uLicenseCheckG),
dsaParams->g);
BN_bin2bn((const unsigned char *)uLicenseCheckP, sizeof(uLicenseCheckP),
dsaParams->p);
BN_bin2bn((const unsigned char *)uLicenseCheckQ, sizeof(uLicenseCheckQ),
dsaParams->q);
BN_bin2bn((const unsigned char *)uLicenseCheckY, sizeof(uLicenseCheckY),
dsaParams->pub_key);
//Create a EVP_PKEY to use in creating a certificate
EVP_PKEY *evpTemp = EVP_PKEY_new();
EVP_PKEY_assign_DSA(evpTemp, dsaParams);
//Create a CMS content info structure out of the license key
CMS_ContentInfo *cms = NULL;
BIO *bioBuff = BIO_new_mem_buf((char *)nBytes, nCountOfBytes);
BIO_set_mem_eof_return(bioBuff,0);
cms = d2i_CMS_bio(bioBuff, NULL);// i believe this finds the end of ASN1
data
STACK_OF(CMS_SignerInfo) *sinfos;
CMS_SignerInfo *si;
sinfos = CMS_get0_SignerInfos(cms);
si = sk_CMS_SignerInfo_value(sinfos, 0);
ASN1_OCTET_STRING* keyid;
X509_NAME* issuer;
ASN1_INTEGER* sno;
int rc = CMS_SignerInfo_get0_signer_id(si, &keyid, &issuer, &sno);
//USE THIS KEYID TO SET THE x509Cert->skid VALUE
printf ("si: %d %p %p %p\n", rc, keyid, issuer, sno);
//create a x509 cert with above DSA params and public key and skid
X509 *x509Cert = X509_new();
X509_set_version(x509Cert, 2);
ASN1_INTEGER_set(X509_get_serialNumber(x509Cert), 0);
x509Cert->skid = ASN1_OCTET_STRING_dup(keyid);
X509_gmtime_adj(X509_get_notBefore(x509Cert),0);
X509_gmtime_adj(X509_get_notAfter(x509Cert), (long) 60*60*24*365);
int error = X509_set_pubkey(x509Cert, evpTemp);
if (error) {
printf("set public key error: %s",
ERR_error_string(ERR_get_error(), NULL));
}
X509_print_fp(stdout, x509Cert);
//create a stack of x509 cert to use it in CMS_verify
STACK_OF(X509) *st=sk_X509_new_null();
sk_X509_push(st, x509Cert);
//x509Cert->skid is valid here
printf ("skid: %p\n", x509Cert->skid);
//It fails here with "signer certificate not found" error
//Also tried using the CMS_NO_CONTENT_VERIFY
int cmsVerify = CMS_verify(cms, st, NULL, NULL, NULL,
CMS_NOINTERN|CMS_NO_SIGNER_CERT_VERIFY);
errortemp = ERR_get_error();
ERR_error_string(errortemp, errorbuff);
printf("countofbytes = %d, error num = %d, and error =
%s\n",nCountOfBytes,errortemp, errorbuff);
//x509Cert->skid is in-valid here
printf ("skid: %p\n", x509Cert->skid);