Re: signature verification. VFY_CreateContextWithAlgorithmID help
On 2010/09/07 17:08 PDT, tedx wrote: I've hacked up something to try but I've now encountered a compilation error that I don't understand. Has anyone else seen this? nss_signing.c: In function ‘spl_nssVerifySignature’: nss_signing.c:172: error: storage size of ‘vfy_context’ isn’t known cc1: warnings being treated as errors nss_signing.c:172: error: unused variable ‘vfy_context’ I suggest you change your warning settings, so that warnings are no longer treated as errors. NSS's type VFYContext is an opaque type. see http://mxr.mozilla.org/security/ident?i=VFYContext You can never declare an instance of it. You can only declare a pointer to it. You get a pointer to it by calling one of the VFY_CreateContext variants. You destroy it by calling VFY_DestroyContext. You never get to see what's inside it, or know how big it is. It appears that you tried to declare a VFYContext variable instance, which was an error, but then you didn't use it, which was also an error. The simplest solution is to get rid of it. :) -- dev-tech-crypto mailing list dev-tech-crypto@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-crypto
Re: signature verification. VFY_CreateContextWithAlgorithmID help
On Sep 8, 3:09 am, Nelson B nel...@bolyard.me wrote: On 2010/09/07 17:08 PDT, tedx wrote: I've hacked up something to try but I've now encountered a compilation error that I don't understand. Has anyone else seen this? nss_signing.c: In function ‘spl_nssVerifySignature’: nss_signing.c:172: error: storage size of ‘vfy_context’ isn’t known cc1: warnings being treated as errors nss_signing.c:172: error: unused variable ‘vfy_context’ I suggest you change your warning settings, so that warnings are no longer treated as errors. NSS's type VFYContext is an opaque type. seehttp://mxr.mozilla.org/security/ident?i=VFYContext You can never declare an instance of it. You can only declare a pointer to it. You get a pointer to it by calling one of the VFY_CreateContext variants. You destroy it by calling VFY_DestroyContext. You never get to see what's inside it, or know how big it is. It appears that you tried to declare a VFYContext variable instance, which was an error, but then you didn't use it, which was also an error. The simplest solution is to get rid of it. :) Oops left the * off the pointer declaration :0, Now I'll see if it works. I am however still concerned that I don't fully understand how to determine the signature algorithms. For testing I generated certificates but in the field someone else will be doing this and I have no visibility into how they do it. You mentioned earlier that some public keys support multiple signature algorithms. How do I determine which algorithms the public key I'm supports? How do I tell VFY about these multiple algorithms? Thanks again for your help. Ted -- dev-tech-crypto mailing list dev-tech-crypto@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-crypto
Re: signature verification. VFY_CreateContextWithAlgorithmID help
On 09/08/2010 05:52 AM, tedx wrote: On Sep 8, 3:09 am, Nelson B nel...@bolyard.me wrote: On 2010/09/07 17:08 PDT, tedx wrote: I've hacked up something to try but I've now encountered a compilation error that I don't understand. Has anyone else seen this? nss_signing.c: In function ‘spl_nssVerifySignature’: nss_signing.c:172: error: storage size of ‘vfy_context’ isn’t known cc1: warnings being treated as errors nss_signing.c:172: error: unused variable ‘vfy_context’ I suggest you change your warning settings, so that warnings are no longer treated as errors. NSS's type VFYContext is an opaque type. seehttp://mxr.mozilla.org/security/ident?i=VFYContext You can never declare an instance of it. You can only declare a pointer to it. You get a pointer to it by calling one of the VFY_CreateContext variants. You destroy it by calling VFY_DestroyContext. You never get to see what's inside it, or know how big it is. It appears that you tried to declare a VFYContext variable instance, which was an error, but then you didn't use it, which was also an error. The simplest solution is to get rid of it. :) Oops left the * off the pointer declaration :0, Now I'll see if it works. I am however still concerned that I don't fully understand how to determine the signature algorithms. Signature algorithm IDs are the NSS representation of the ASN wrapping for signatures. All normal signatures have them, most notably certificates and PKCS #7/CMS signed blobs (S/MIME). The idea behind using them in your application is you can always ask NSS to extract them from your ANS.1 blob, and you as an application do not need to add any special code for handling various types of hash/signing algorihtms When we add new hash/signing algorithms occur, I will usually encapsulate all that knowledge into secvfy.c It will parse the parameters in the asn.1 signatureAlgorithm, so you as an application don't need to deal with that. Your sample app does not provide an ASN.1 encoded signature, in fact it does not provide any indication about how the data was signed (which if you use that in a protocol, you may find some issues). If you are setting up your own protocol, I highly suggest that you at least ASN.1 sign your data, and preferably use pkcs #7. This is the primary reason you are having a hard time finding examples, you are trying do so all these functions at a very low level. If you are trying to match an existing protocol that does not use ANS.1, then you really want to use VFY_CreateContextDirect. Finally you are going way low level. You should try using the SGN functions rather than going directly to the PK11 underlying function calls. PK11_Sign is not likely to do what you think it does (It does not add the RSA PKCS #1 DER encoding oid, so your signatures will not verify). Difference between various asymmetric signing algorithms are still visible at the PKCS #11 level. My guess is you are probably running into a bug I just noticed from inspection. This will case both SGN and VFY to fail for RSA SHA-2 signatures, except for the VFY_CreateContextDirect case. === RCS file: /cvsroot/mozilla/security/nss/lib/cryptohi/secvfy.c,v retrieving revision 1.24 diff -u -r1.24 secvfy.c --- secvfy.c23 Jun 2010 02:13:56 -1.24 +++ secvfy.c8 Sep 2010 23:44:35 - @@ -240,7 +240,15 @@ case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: *hashalg = SEC_OID_UNKNOWN; /* get it from the RSA signature */ break; - + case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: +*hashalg = SEC_OID_SHA256; +break; + case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: +*hashalg = SEC_OID_SHA384; +break; + case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: +*hashalg = SEC_OID_SHA512; +break; case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: *hashalg = SEC_OID_SHA256; bobs-laptop(367) For testing I generated certificates but in the field someone else will be doing this and I have no visibility into how they do it. You mentioned earlier that some public keys support multiple signature algorithms. How do I determine which algorithms the public key I'm supports? How do I tell VFY about these multiple algorithms? Thanks again for your help. Ted -- dev-tech-crypto mailing list dev-tech-crypto@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-crypto
Re: signature verification. VFY_CreateContextWithAlgorithmID help
On 2010-09-06 08:17 PDT, Xavier Toth wrote: I'm trying to verify the signature of a file I've signed but I don't understand where to get the sigAlgorithm and hash to pass to VFY_CreateContextWithAlgorithmID. I presume you've read the description of these parameters in http://mxr.mozilla.org/security/source/security/nss/lib/cryptohi/cryptohi.h#227 In particular, note that the description tells us that the hash argument is optional (meaning that you can pass NULL as the argument value for this parameter) and that when present, it is the address into which the function returns (outputs) the type of hash that it found within the signature itself. Not all types of signatures embed that information, and for them, the hash info must be input, using one of the other variants of this function. I've googled looking for some sample code using the VFY_ apis to verify signatures but I haven't found anything that I could build off of. http://mxr.mozilla.org/security/search?string=VFY_CreateContext reveals that there are 3 variants of VFY_CreateContext, including VFY_CreateContextDirect and VFY_CreateContextWithAlgorithmID. It also reveals that, within the Mozilla code that uses NSS, there are NO callers of VFY_CreateContextDirect, and only one caller of VFY_CreateContextWithAlgorithmID. All the rest use the original VFY_CreateContext function. Still, I think that one example ought to suffice. Shouldn't I be able to get these from the public key and/or signature itself? Some public keys support multiple types of signature algorithms. You must tell the VFY function which of the signature algorithms to use. Many (most?) of the standard signature formats record that information explicitly in the form of an OID, but some do not. -- /Nelson Bolyard -- dev-tech-crypto mailing list dev-tech-crypto@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-crypto
Re: signature verification. VFY_CreateContextWithAlgorithmID help
On Sep 7, 1:34 pm, Nelson B Bolyard nel...@bolyard.me wrote: On 2010-09-06 08:17 PDT, Xavier Toth wrote: I'm trying to verify the signature of a file I've signed but I don't understand where to get the sigAlgorithm and hash to pass to VFY_CreateContextWithAlgorithmID. I presume you've read the description of these parameters inhttp://mxr.mozilla.org/security/source/security/nss/lib/cryptohi/cryp... In particular, note that the description tells us that the hash argument is optional (meaning that you can pass NULL as the argument value for this parameter) and that when present, it is the address into which the function returns (outputs) the type of hash that it found within the signature itself. Not all types of signatures embed that information, and for them, the hash info must be input, using one of the other variants of this function. I've googled looking for some sample code using the VFY_ apis to verify signatures but I haven't found anything that I could build off of. http://mxr.mozilla.org/security/search?string=VFY_CreateContext reveals that there are 3 variants of VFY_CreateContext, including VFY_CreateContextDirect and VFY_CreateContextWithAlgorithmID. It also reveals that, within the Mozilla code that uses NSS, there are NO callers of VFY_CreateContextDirect, and only one caller of VFY_CreateContextWithAlgorithmID. All the rest use the original VFY_CreateContext function. Still, I think that one example ought to suffice. Shouldn't I be able to get these from the public key and/or signature itself? Some public keys support multiple types of signature algorithms. You must tell the VFY function which of the signature algorithms to use. Many (most?) of the standard signature formats record that information explicitly in the form of an OID, but some do not. -- /Nelson Bolyard I appreciate your response however I must say that the one example is pretty useless (possibly because this is my first time working with NSS). I've hacked up something to try but I've now encountered a compilation error that I don't understand. Has anyone else seen this? The source includes: #include nss.h #include cert.h #include key.h #include sechash.h #include cryptohi.h make[1]: Entering directory `/home/tedx/sidecar/cds-sidecar-library/ common/src' cc -Werror -Wall -W -Wundef -Wshadow -Wmissing-noreturn -Wmissing- format-attribute -g3 -O0 -gdwarf-2 -fno-strict-aliasing -I. -I../ include -D_GNU_SOURCE -I/usr/include/nss3 -I/usr/include/nspr4 `xml2- config --cflags` -fprofile-arcs -ftest-coverage -fPIC -c -o nss_signing.o nss_signing.c nss_signing.c: In function ‘spl_nssVerifySignature’: nss_signing.c:172: error: storage size of ‘vfy_context’ isn’t known cc1: warnings being treated as errors nss_signing.c:172: error: unused variable ‘vfy_context’ make[1]: *** [nss_signing.o] Error 1 make[1]: Leaving directory `/home/tedx/sidecar/cds-sidecar-library/ common/src' make: *** [all] Error 1 -- dev-tech-crypto mailing list dev-tech-crypto@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-crypto
signature verification. VFY_CreateContextWithAlgorithmID help
I'm trying to verify the signature of a file I've signed but I don't understand where to get the sigAlgorithm and hash to pass to VFY_CreateContextWithAlgorithmID. I've googled looking for some sample code using the VFY_ apis to verify signatures but I haven't found anything that I could build off of. Shouldn't I be able to get these from the public key and/or signature itself? int spl_nssSignSHA256(const char *certNickname, const char *certpw, const char *certdbpw, const char *certDir, const char *data, const char *filename, unsigned char **signature, char **error) { int result = 0; CERTCertificate *cert = NULL; SECKEYPrivateKey *pvtkey = NULL; unsigned char hash_buf[SHA256_LENGTH]; SECItem hash, sign; PK11Context *hashcx = NULL; SECStatus rc; if ((data != NULL filename != NULL) || (data == NULL filename == NULL)) { asprintf(error, Error invalid arguments); result = -1; goto cleanup; } hash.len = sizeof(hash_buf); hash.data = hash_buf; if (certDir != NULL) rc = NSS_Init(certDir); else rc = NSS_Init(SPL_NSSCERTDIR); if (rc != SECSuccess) { asprintf(error, Error initializing NSS (%d), PR_GetError()); result = -1; goto cleanup; } PK11_SetPasswordFunc(spl_nssPasswdCB); cert = PK11_FindCertFromNickname(certNickname, (void *)certdbpw); if (cert == NULL) { asprintf(error, Couldn't find cert for %s in NSS db (err %d), certNickname, PR_GetError()); result = -1; goto cleanup; } pvtkey = PK11_FindKeyByAnyCert(cert, (void *)certpw); if (pvtkey == NULL) { asprintf(error, Couldn't find private key for cert %s (err %d), certNickname, PR_GetError()); result = -1; goto cleanup; } hashcx = PK11_CreateDigestContext(SEC_OID_SHA256); if (hashcx == NULL) { asprintf(error, Error creating SHA526 digest (%d), PR_GetError()); result = -1; goto cleanup; } if (filename != NULL) { int fd = 0; int bytesRead = 0; int buflen = 1024; char *buf = (char *)malloc(buflen); if ((fd = open(filename, O_RDONLY)) 0) { asprintf(error, Error opening %s - %s, filename, strerror(errno)); result = -1; goto cleanup; } while ((bytesRead = read(fd, buf, buflen)) 0) { PK11_DigestOp(hashcx, (const unsigned char *)buf, bytesRead); } free(buf); close(fd); if (bytesRead 0) { asprintf(error, Error reading %s - %s, filename, strerror(errno)); result = -1; goto cleanup; } } else PK11_DigestOp(hashcx, (const unsigned char *)data, strlen(data)); PK11_DigestFinal(hashcx, hash.data, hash.len, hash.len); if (hash.len != SHA256_LENGTH) { asprintf(error, Digest length was not correct); result = -1; goto cleanup; } sign.len = PK11_SignatureLen(pvtkey); if (sign.len = 0) { asprintf(error, Invalid private key); result = -1; goto cleanup; } sign.data = (unsigned char *)malloc(sign.len); if (sign.data == NULL) { perror(Error allocating memory); result = -1; goto cleanup; } /* sign the hash */ rc = PK11_Sign(pvtkey, sign, hash); if (rc != SECSuccess) { asprintf(error, Error signing data %d, PR_GetError()); free(sign.data); result = -1; goto cleanup; } *signature = sign.data; result = 0; cleanup: if (cert) CERT_DestroyCertificate(cert); if (pvtkey) SECKEY_DestroyPrivateKey(pvtkey); if (hashcx) PK11_DestroyContext(hashcx, PR_TRUE); NSS_Shutdown(); return result; } int spl_nssVerifySignature(const char *certNickname, const char *certdbpw, const char *certDir, const char *data, const char *filename, unsigned char *signature, char **error) { int result = 0; CERTCertificate *cert = NULL; CERTSubjectPublicKeyInfo *spki; SECKEYPublicKey *pubkey = NULL;