Man page of CMS_verify says the following

CMS_get0_signers() retrieves the signing certificate(s) from *cms*, it must
be called after a successful CMS_verify() operation.

So, CMS_get0_signers should be called after CMS_verify but you seem to do it
the other way round. Secondly, why do you need to build the X509 cert from
the DSA parameters? When your C# application creates the CMS signed message,
does it not use a Certificate and its Private Key? Your stack of certs
should include this certificate. I also presume that the signing certificate
isn't included in the contentInfo message as you have set the CMS_NOINTERN
flag for CMS_verify.

Thanks,
Sandeep

On Wed, Jan 27, 2010 at 5:36 AM, Ujwal Chinthala <ujwal_chinth...@net.com>wrote:

>  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);
>
>
>
>
>
>
>

Reply via email to