int oauth_verify_rsa_sha1 (const char *m, const char *c, const char *sig) { PK11SlotInfo *slot = NULL; SECKEYPublicKey *pkey = NULL; CERTCertificate *cert = NULL; SECItem signature; SECStatus s; SECItem der; int rv=0; char *key = oauth_strip_pkcs(c, NS_CERT_HEADER, NS_CERT_TRAILER); if (!key) return 0; oauth_init_nss(); s = ATOB_ConvertAsciiToItem(&signature, (char*) sig); // XXX cast (const char*) -> (char*) if (s != SECSuccess) goto looser; slot = PK11_GetInternalKeySlot(); if (!slot) goto looser; s = ATOB_ConvertAsciiToItem(&der, key); if (s != SECSuccess) goto looser; cert = __CERT_DecodeDERCertificate(&der, PR_TRUE, NULL); SECITEM_FreeItem(&der, PR_FALSE); if (!cert) goto looser; pkey = CERT_ExtractPublicKey(cert); if (!pkey) goto looser; if (pkey->keyType != rsaKey) goto looser; s = VFY_VerifyData((unsigned char*) m, strlen(m), pkey, &signature, SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE, NULL); if (s == SECSuccess) rv=1; #if 0 else if (PR_GetError()!= SEC_ERROR_BAD_SIGNATURE) rv=-1; #endif looser: if (pkey) SECKEY_DestroyPublicKey(pkey); if (slot) PK11_FreeSlot(slot); free(key); return rv; }
char *oauth_body_hash_file(char *filename) { PK11SlotInfo *slot = NULL; PK11Context *context = NULL; unsigned char digest[20]; // Is there a way to tell how large the output is? unsigned int len; SECStatus s; char *rv=NULL; size_t bl; unsigned char fb[BUFSIZ]; FILE *F= fopen(filename, "r"); if (!F) return NULL; oauth_init_nss(); slot = PK11_GetInternalKeySlot(); if (!slot) goto looser; context = PK11_CreateDigestContext(SEC_OID_SHA1); if (!context) goto looser; s = PK11_DigestBegin(context); if (s != SECSuccess) goto looser; while (!feof(F) && (bl=fread(fb,sizeof(char),BUFSIZ, F))>0) { s = PK11_DigestOp(context, (unsigned char*) fb, bl); if (s != SECSuccess) goto looser; } s = PK11_DigestFinal(context, digest, &len, sizeof digest); if (s != SECSuccess) goto looser; unsigned char *dgst = xmalloc(len*sizeof(char)); // oauth_body_hash_encode frees the digest.. memcpy(dgst, digest, len); rv=oauth_body_hash_encode(len, dgst); looser: fclose(F); if (context) PK11_DestroyContext(context, PR_TRUE); if (slot) PK11_FreeSlot(slot); return rv; }