Re: signature verification. VFY_CreateContextWithAlgorithmID help

2010-09-08 Thread Nelson B
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

2010-09-08 Thread tedx
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

2010-09-08 Thread Robert Relyea
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

2010-09-07 Thread Nelson B Bolyard
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

2010-09-07 Thread tedx
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

2010-09-06 Thread tedx
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;