Bug 320583 Support for SHA256/384/512 with ECC signing
This commit is contained in:
Родитель
f215fa13a0
Коммит
a855b8fda9
|
@ -2153,17 +2153,11 @@ SignCert(CERTCertificate *cert,
|
|||
|
||||
arena = cert->arena;
|
||||
|
||||
switch(caPrivateKey->keyType) {
|
||||
case rsaKey:
|
||||
algID = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
|
||||
break;
|
||||
case dsaKey:
|
||||
algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
|
||||
break;
|
||||
default:
|
||||
algID = SEC_GetSignatureAlgorithmOidTag(caPrivateKey->keyType,
|
||||
SEC_OID_UNKNOWN);
|
||||
if (algID == SEC_OID_UNKNOWN) {
|
||||
error_out("ERROR: Unknown key type for issuer.");
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
|
||||
rv = SECOID_SetAlgorithmID(arena, &cert->signature, algID, 0);
|
||||
|
|
|
@ -146,48 +146,6 @@ void checkName(CERTName *n, char *fieldName, int verbose)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Private version of verification that checks for agreement between
|
||||
* signature algorithm oid (at the SignedData level) and oid in DigestInfo.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* Returns the tag for the hash algorithm in the given signature algorithm */
|
||||
static
|
||||
int hashAlg(int sigAlgTag) {
|
||||
int rv;
|
||||
switch(sigAlgTag) {
|
||||
case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
|
||||
rv = SEC_OID_MD2;
|
||||
break;
|
||||
case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
|
||||
rv = SEC_OID_MD5;
|
||||
break;
|
||||
case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
|
||||
rv = SEC_OID_SHA1;
|
||||
break;
|
||||
default:
|
||||
rv = -1;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct VFYContextStr {
|
||||
int alg;
|
||||
unsigned char digest[32];
|
||||
void *hasher;
|
||||
void (*begin)(void *);
|
||||
void (*update)(void *, unsigned char*, unsigned);
|
||||
SECStatus (*end)(void *, unsigned char*, unsigned int*, unsigned);
|
||||
void (*destroy)(void *, PRBool);
|
||||
};
|
||||
|
||||
|
||||
static
|
||||
SECStatus
|
||||
OurVerifyData(unsigned char *buf, int len, SECKEYPublicKey *key,
|
||||
|
@ -200,8 +158,8 @@ OurVerifyData(unsigned char *buf, int len, SECKEYPublicKey *key,
|
|||
int hashAlgTag;
|
||||
int showDigestOid=0;
|
||||
|
||||
cx = VFY_CreateContext(key, sig, SECOID_GetAlgorithmTag(sigAlgorithm),
|
||||
NULL);
|
||||
cx = VFY_CreateContextWithAlgorithmID(key, sig, sigAlgorithm, &hashAlgTag,
|
||||
NULL);
|
||||
if (cx == NULL)
|
||||
return SECFailure;
|
||||
|
||||
|
@ -210,18 +168,9 @@ OurVerifyData(unsigned char *buf, int len, SECKEYPublicKey *key,
|
|||
return SECFailure;
|
||||
sigAlgTag = sigAlgOid->offset;
|
||||
|
||||
hashAlgTag = hashAlg(sigAlgTag);
|
||||
if (hashAlgTag == -1) {
|
||||
printf("PROBLEM: Unsupported Digest Algorithm in DigestInfo");
|
||||
showDigestOid = 1;
|
||||
} else if (hashAlgTag != cx->alg) {
|
||||
printf("PROBLEM: Digest OID in DigestInfo is incompatible "
|
||||
"with Signature Algorithm\n");
|
||||
showDigestOid = 1;
|
||||
}
|
||||
|
||||
if (showDigestOid) {
|
||||
oiddata = SECOID_FindOIDByTag(cx->alg);
|
||||
oiddata = SECOID_FindOIDByTag(hashAlgTag);
|
||||
if ( oiddata ) {
|
||||
printf("PROBLEM: (cont) Digest OID is %s\n", oiddata->desc);
|
||||
} else {
|
||||
|
|
|
@ -414,14 +414,9 @@ createNewCert(CERTCertificate**issuedCert,CERTCertificateRequest *oldCertReq,
|
|||
if (issuerPrivKey == NULL) {
|
||||
rv = COULD_NOT_FIND_ISSUER_PRIVATE_KEY;
|
||||
}
|
||||
switch(issuerPrivKey->keyType) {
|
||||
case rsaKey:
|
||||
signTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
|
||||
break;
|
||||
case dsaKey:
|
||||
signTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
|
||||
break;
|
||||
default:
|
||||
signTag = SEC_GetSignatureAlgorithmOidTag(issuerPrivatekey->keytype,
|
||||
SEC_OID_UNKNOWN);
|
||||
if (signTag == SEC_OID_UNKNOWN) {
|
||||
rv = UNSUPPORTED_SIGN_OPERATION_FOR_ISSUER;
|
||||
goto loser;
|
||||
}
|
||||
|
@ -644,8 +639,8 @@ verifySignature(CGIVarTable *varTable, CRMFCertReqMsg *currReq,
|
|||
rv = ERROR_ENCODING_CERT_REQ_FOR_POP;
|
||||
goto loser;
|
||||
}
|
||||
srv = VFY_VerifyData(reqDER->data, reqDER->len, pubKey, signature,
|
||||
SECOID_FindOIDTag(&algID->algorithm), varTable);
|
||||
srv = VFY_VerifyDataWithAlgorithmID(reqDER->data, reqDER->len, pubKey,
|
||||
signature, &algID->algorithm, NULL, varTable);
|
||||
if (srv != SECSuccess) {
|
||||
rv = ERROR_VERIFYING_SIGNATURE_POP;
|
||||
goto loser;
|
||||
|
|
|
@ -455,18 +455,10 @@ sign_cert(CERTCertificate *cert, SECKEYPrivateKey *privk)
|
|||
void *dummy;
|
||||
SECOidTag alg = SEC_OID_UNKNOWN;
|
||||
|
||||
switch (privk->keyType) {
|
||||
case rsaKey:
|
||||
alg = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
|
||||
break;
|
||||
|
||||
case dsaKey:
|
||||
alg = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
|
||||
break;
|
||||
default:
|
||||
alg = SEC_GetSignatureAlgorithmOidTag(privk->keyType, SEC_OID_UNKNOWN);
|
||||
if (alg == SEC_OID_UNKNOWN) {
|
||||
FatalError("Unknown key type");
|
||||
}
|
||||
PORT_Assert(alg != SEC_OID_UNKNOWN);
|
||||
|
||||
rv = SECOID_SetAlgorithmID (cert->arena, &cert->signature, alg, 0);
|
||||
|
||||
|
|
|
@ -101,7 +101,6 @@ CERT_VerifySignedDataWithPublicKey(CERTSignedData *sd,
|
|||
void *wincx)
|
||||
{
|
||||
SECStatus rv;
|
||||
SECOidTag algid;
|
||||
SECItem sig;
|
||||
|
||||
if ( !pubKey || !sd ) {
|
||||
|
@ -114,9 +113,8 @@ CERT_VerifySignedDataWithPublicKey(CERTSignedData *sd,
|
|||
/* convert sig->len from bit counts to byte count. */
|
||||
DER_ConvertBitString(&sig);
|
||||
|
||||
algid = SECOID_GetAlgorithmTag(&sd->signatureAlgorithm);
|
||||
rv = VFY_VerifyData(sd->data.data, sd->data.len, pubKey, &sig,
|
||||
algid, wincx);
|
||||
rv = VFY_VerifyDataWithAlgorithmID(sd->data.data, sd->data.len, pubKey,
|
||||
&sig, &sd->signatureAlgorithm, NULL, wincx);
|
||||
|
||||
return rv ? SECFailure : SECSuccess;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
* Implementation of OCSP services, for both client and server.
|
||||
* (XXX, really, mostly just for client right now, but intended to do both.)
|
||||
*
|
||||
* $Id: ocsp.c,v 1.22 2006-02-03 18:13:04 kaie%kuix.de Exp $
|
||||
* $Id: ocsp.c,v 1.23 2006-02-08 06:13:57 rrelyea%redhat.com Exp $
|
||||
*/
|
||||
|
||||
#include "prerror.h"
|
||||
|
@ -2678,10 +2678,9 @@ ocsp_CheckSignature(ocspSignature *signature, void *tbs,
|
|||
*/
|
||||
DER_ConvertBitString(&rawSignature);
|
||||
|
||||
rv = VFY_VerifyData(encodedTBS->data, encodedTBS->len, signerKey,
|
||||
&rawSignature,
|
||||
SECOID_GetAlgorithmTag(&signature->signatureAlgorithm),
|
||||
pwArg);
|
||||
rv = VFY_VerifyDataWithAlgorithmID(encodedTBS->data, encodedTBS->len,
|
||||
signerKey, &rawSignature,
|
||||
&signature->signatureAlgorithm, NULL, pwArg);
|
||||
|
||||
finish:
|
||||
if (signature->wasChecked)
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: cryptohi.h,v 1.9 2005-03-08 07:08:48 julien.pierre.bugs%sun.com Exp $ */
|
||||
/* $Id: cryptohi.h,v 1.10 2006-02-08 06:14:07 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#ifndef _CRYPTOHI_H_
|
||||
#define _CRYPTOHI_H_
|
||||
|
@ -65,7 +65,7 @@ SEC_BEGIN_PROTOS
|
|||
* functions convert between formats.
|
||||
*/
|
||||
extern SECStatus DSAU_EncodeDerSig(SECItem *dest, SECItem *src);
|
||||
extern SECItem *DSAU_DecodeDerSig(SECItem *item);
|
||||
extern SECItem *DSAU_DecodeDerSig(const SECItem *item);
|
||||
|
||||
/*
|
||||
* Unlike DSA, raw ECDSA signatures do not have a fixed length.
|
||||
|
@ -81,7 +81,7 @@ extern SECItem *DSAU_DecodeDerSig(SECItem *item);
|
|||
*/
|
||||
extern SECStatus DSAU_EncodeDerSigWithLen(SECItem *dest, SECItem *src,
|
||||
unsigned int len);
|
||||
extern SECItem *DSAU_DecodeDerSigToLen(SECItem *item, unsigned int len);
|
||||
extern SECItem *DSAU_DecodeDerSigToLen(const SECItem *item, unsigned int len);
|
||||
|
||||
/****************************************/
|
||||
/*
|
||||
|
@ -186,18 +186,60 @@ extern SECOidTag SEC_GetSignatureAlgorithmOidTag(KeyType keyType,
|
|||
** Signature verification operations
|
||||
*/
|
||||
|
||||
/*
|
||||
** Create a signature verification context. This version is deprecated,
|
||||
** This function is deprecated. Use VFY_CreateContextDirect or
|
||||
** VFY_CreateContextWithAlgorithmID instead.
|
||||
** "key" the public key to verify with
|
||||
** "sig" the encrypted signature data if sig is NULL then
|
||||
** VFY_EndWithSignature must be called with the correct signature at
|
||||
** the end of the processing.
|
||||
** "sigAlg" specifies the signing algorithm to use (including the
|
||||
** hash algorthim). This must match the key type.
|
||||
** "wincx" void pointer to the window context
|
||||
*/
|
||||
extern VFYContext *VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig,
|
||||
SECOidTag sigAlg, void *wincx);
|
||||
/*
|
||||
** Create a signature verification context.
|
||||
** "key" the public key to verify with
|
||||
** "sig" the encrypted signature data if sig is NULL then
|
||||
** VFY_EndWithSignature must be called with the correct signature at
|
||||
** the end of the processing.
|
||||
** "algid" specifies the signing algorithm to use. This must match
|
||||
** the key type.
|
||||
** "pubkAlg" specifies the cryptographic signing algorithm to use (the
|
||||
** raw algorithm without any hash specified. This must match the key
|
||||
** type.
|
||||
** "hashAlg" specifies the hashing algorithm used. If the key is an
|
||||
** RSA key, and sig is not NULL, then hashAlg can be SEC_OID_UNKNOWN.
|
||||
** the hash is selected from data in the sig.
|
||||
** "hash" optional pointer to return the actual hash algorithm used.
|
||||
** in practice this should always match the passed in hashAlg (the
|
||||
** exception is the case where hashAlg is SEC_OID_UNKNOWN above).
|
||||
** If this value is NULL no, hash oid is returned.
|
||||
** "wincx" void pointer to the window context
|
||||
*/
|
||||
extern VFYContext *VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig,
|
||||
SECOidTag algid, void *wincx);
|
||||
extern VFYContext *VFY_CreateContextDirect(const SECKEYPublicKey *key,
|
||||
const SECItem *sig,
|
||||
SECOidTag pubkAlg,
|
||||
SECOidTag hashAlg,
|
||||
SECOidTag *hash, void *wincx);
|
||||
/*
|
||||
** Create a signature verification context from a algorithm ID.
|
||||
** "key" the public key to verify with
|
||||
** "sig" the encrypted signature data if sig is NULL then
|
||||
** VFY_EndWithSignature must be called with the correct signature at
|
||||
** the end of the processing.
|
||||
** "algid" specifies the signing algorithm and parameters to use.
|
||||
** This must match the key type.
|
||||
** "hash" optional pointer to return the oid of the actual hash used in
|
||||
** the signature. If this value is NULL no, hash oid is returned.
|
||||
** "wincx" void pointer to the window context
|
||||
*/
|
||||
extern VFYContext *VFY_CreateContextWithAlgorithmID(const SECKEYPublicKey *key,
|
||||
const SECItem *sig,
|
||||
const SECAlgorithmID *algid,
|
||||
SECOidTag *hash,
|
||||
void *wincx);
|
||||
|
||||
/*
|
||||
** Destroy a verification-context object.
|
||||
|
@ -216,7 +258,7 @@ extern SECStatus VFY_Begin(VFYContext *cx);
|
|||
** "input" the input data
|
||||
** "inputLen" the amount of input data
|
||||
*/
|
||||
extern SECStatus VFY_Update(VFYContext *cx, unsigned char *input,
|
||||
extern SECStatus VFY_Update(VFYContext *cx, const unsigned char *input,
|
||||
unsigned int inputLen);
|
||||
|
||||
/*
|
||||
|
@ -246,14 +288,93 @@ extern SECStatus VFY_EndWithSignature(VFYContext *cx, SECItem *sig);
|
|||
** Verify the signature on a block of data for which we already have
|
||||
** the digest. The signature data is an RSA private key encrypted
|
||||
** block of data formatted according to PKCS#1.
|
||||
** This function is deprecated. Use VFY_VerifyDigestDirect or
|
||||
** VFY_VerifyDigestWithAlgorithmID instead.
|
||||
** "dig" the digest
|
||||
** "key" the public key to check the signature with
|
||||
** "sig" the encrypted signature data
|
||||
** "algid" specifies the signing algorithm to use. This must match
|
||||
** "sigAlg" specifies the signing algorithm to use. This must match
|
||||
** the key type.
|
||||
** "wincx" void pointer to the window context
|
||||
**/
|
||||
extern SECStatus VFY_VerifyDigest(SECItem *dig, SECKEYPublicKey *key,
|
||||
SECItem *sig, SECOidTag algid, void *wincx);
|
||||
SECItem *sig, SECOidTag sigAlg, void *wincx);
|
||||
/*
|
||||
** Verify the signature on a block of data for which we already have
|
||||
** the digest. The signature data is an RSA private key encrypted
|
||||
** block of data formatted according to PKCS#1.
|
||||
** "dig" the digest
|
||||
** "key" the public key to check the signature with
|
||||
** "sig" the encrypted signature data
|
||||
** "pubkAlg" specifies the cryptographic signing algorithm to use (the
|
||||
** raw algorithm without any hash specified. This must match the key
|
||||
** type.
|
||||
** "hashAlg" specifies the hashing algorithm used.
|
||||
** "wincx" void pointer to the window context
|
||||
**/
|
||||
extern SECStatus VFY_VerifyDigestDirect(const SECItem *dig,
|
||||
const SECKEYPublicKey *key,
|
||||
const SECItem *sig, SECOidTag pubkAlg,
|
||||
SECOidTag hashAlg, void *wincx);
|
||||
/*
|
||||
** Verify the signature on a block of data for which we already have
|
||||
** the digest. The signature data is an RSA private key encrypted
|
||||
** block of data formatted according to PKCS#1.
|
||||
** "key" the public key to verify with
|
||||
** "sig" the encrypted signature data if sig is NULL then
|
||||
** VFY_EndWithSignature must be called with the correct signature at
|
||||
** the end of the processing.
|
||||
** "algid" specifies the signing algorithm and parameters to use.
|
||||
** This must match the key type.
|
||||
** "hash" oid of the actual hash used to create digest. If this value is
|
||||
** not set to SEC_OID_UNKNOWN, it must match the hash of the signature.
|
||||
** "wincx" void pointer to the window context
|
||||
*/
|
||||
extern SECStatus VFY_VerifyDigestWithAlgorithmID(const SECItem *dig,
|
||||
const SECKEYPublicKey *key, const SECItem *sig,
|
||||
const SECAlgorithmID *algid, SECOidTag hash,
|
||||
void *wincx);
|
||||
|
||||
/*
|
||||
** Verify the signature on a block of data. The signature data is an RSA
|
||||
** private key encrypted block of data formatted according to PKCS#1.
|
||||
** This function is deprecated. Use VFY_VerifyDataDirect or
|
||||
** VFY_VerifyDataWithAlgorithmID instead.
|
||||
** "buf" the input data
|
||||
** "len" the length of the input data
|
||||
** "key" the public key to check the signature with
|
||||
** "sig" the encrypted signature data
|
||||
** "sigAlg" specifies the signing algorithm to use. This must match
|
||||
** the key type.
|
||||
** "wincx" void pointer to the window context
|
||||
*/
|
||||
extern SECStatus VFY_VerifyData(unsigned char *buf, int len,
|
||||
SECKEYPublicKey *key, SECItem *sig,
|
||||
SECOidTag sigAlg, void *wincx);
|
||||
/*
|
||||
** Verify the signature on a block of data. The signature data is an RSA
|
||||
** private key encrypted block of data formatted according to PKCS#1.
|
||||
** "buf" the input data
|
||||
** "len" the length of the input data
|
||||
** "key" the public key to check the signature with
|
||||
** "sig" the encrypted signature data
|
||||
** "pubkAlg" specifies the cryptographic signing algorithm to use (the
|
||||
** raw algorithm without any hash specified. This must match the key
|
||||
** type.
|
||||
** "hashAlg" specifies the hashing algorithm used. If the key is an
|
||||
** RSA key, and sig is not NULL, then hashAlg can be SEC_OID_UNKNOWN.
|
||||
** the hash is selected from data in the sig.
|
||||
** "hash" optional pointer to return the actual hash algorithm used.
|
||||
** in practice this should always match the passed in hashAlg (the
|
||||
** exception is the case where hashAlg is SEC_OID_UNKNOWN above).
|
||||
** If this value is NULL no, hash oid is returned.
|
||||
** "wincx" void pointer to the window context
|
||||
*/
|
||||
extern SECStatus VFY_VerifyDataDirect(const unsigned char *buf, int len,
|
||||
const SECKEYPublicKey *key,
|
||||
const SECItem *sig,
|
||||
SECOidTag pubkAlg, SECOidTag hashAlg,
|
||||
SECOidTag *hash, void *wincx);
|
||||
|
||||
/*
|
||||
** Verify the signature on a block of data. The signature data is an RSA
|
||||
|
@ -262,12 +383,17 @@ extern SECStatus VFY_VerifyDigest(SECItem *dig, SECKEYPublicKey *key,
|
|||
** "len" the length of the input data
|
||||
** "key" the public key to check the signature with
|
||||
** "sig" the encrypted signature data
|
||||
** "algid" specifies the signing algorithm to use. This must match
|
||||
** the key type.
|
||||
** "algid" specifies the signing algorithm and parameters to use.
|
||||
** This must match the key type.
|
||||
** "hash" optional pointer to return the oid of the actual hash used in
|
||||
** the signature. If this value is NULL no, hash oid is returned.
|
||||
** "wincx" void pointer to the window context
|
||||
*/
|
||||
extern SECStatus VFY_VerifyData(unsigned char *buf, int len,
|
||||
SECKEYPublicKey *key, SECItem *sig,
|
||||
SECOidTag algid, void *wincx);
|
||||
extern SECStatus VFY_VerifyDataWithAlgorithmID(const unsigned char *buf,
|
||||
int len, const SECKEYPublicKey *key,
|
||||
const SECItem *sig,
|
||||
const SECAlgorithmID *algid, SECOidTag *hash,
|
||||
void *wincx);
|
||||
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
|
|
@ -192,7 +192,7 @@ common_EncodeDerSig(SECItem *dest, SECItem *src)
|
|||
** For ECDSA, len depends on the key size used to create the signature.
|
||||
*/
|
||||
static SECItem *
|
||||
common_DecodeDerSig(SECItem *item, unsigned int len)
|
||||
common_DecodeDerSig(const SECItem *item, unsigned int len)
|
||||
{
|
||||
SECItem * result = NULL;
|
||||
SECStatus status;
|
||||
|
@ -283,7 +283,7 @@ DSAU_EncodeDerSigWithLen(SECItem *dest, SECItem *src, unsigned int len)
|
|||
** followed by 20 bytes of s.
|
||||
*/
|
||||
SECItem *
|
||||
DSAU_DecodeDerSig(SECItem *item)
|
||||
DSAU_DecodeDerSig(const SECItem *item)
|
||||
{
|
||||
return common_DecodeDerSig(item, DSA_SUBPRIME_LEN);
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ DSAU_DecodeDerSig(SECItem *item)
|
|||
** r followed by s (both padded to take up exactly len/2 bytes).
|
||||
*/
|
||||
SECItem *
|
||||
DSAU_DecodeDerSigToLen(SECItem *item, unsigned int len)
|
||||
DSAU_DecodeDerSigToLen(const SECItem *item, unsigned int len)
|
||||
{
|
||||
return common_DecodeDerSig(item, len/2);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: keyhi.h,v 1.13 2005-09-02 01:24:42 wtchang%redhat.com Exp $ */
|
||||
/* $Id: keyhi.h,v 1.14 2006-02-08 06:14:07 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#ifndef _KEYHI_H_
|
||||
#define _KEYHI_H_
|
||||
|
@ -82,22 +82,22 @@ SECKEY_KEAParamCompare(CERTCertificate *cert1,CERTCertificate *cert2);
|
|||
/*
|
||||
** Return the strength of the public key in bytes
|
||||
*/
|
||||
extern unsigned SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk);
|
||||
extern unsigned SECKEY_PublicKeyStrength(const SECKEYPublicKey *pubk);
|
||||
|
||||
/*
|
||||
** Return the strength of the public key in bits
|
||||
*/
|
||||
extern unsigned SECKEY_PublicKeyStrengthInBits(SECKEYPublicKey *pubk);
|
||||
extern unsigned SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk);
|
||||
|
||||
/*
|
||||
** Make a copy of the private key "privKey"
|
||||
*/
|
||||
extern SECKEYPrivateKey *SECKEY_CopyPrivateKey(SECKEYPrivateKey *privKey);
|
||||
extern SECKEYPrivateKey *SECKEY_CopyPrivateKey(const SECKEYPrivateKey *privKey);
|
||||
|
||||
/*
|
||||
** Make a copy of the public key "pubKey"
|
||||
*/
|
||||
extern SECKEYPublicKey *SECKEY_CopyPublicKey(SECKEYPublicKey *pubKey);
|
||||
extern SECKEYPublicKey *SECKEY_CopyPublicKey(const SECKEYPublicKey *pubKey);
|
||||
|
||||
/*
|
||||
** Convert a private key "privateKey" into a public key
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Red Hat, Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bob Relyea, Red Hat
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: keyi.h,v 1.1 2006-02-08 06:14:07 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#ifndef _KEYI_H_
|
||||
#define _KEYI_H_
|
||||
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
/* NSS private functions */
|
||||
/* map an oid to a keytype... actually this function and it's converse
|
||||
* are good candidates for public functions.. */
|
||||
KeyType seckey_GetKeyType(SECOidTag pubKeyOid);
|
||||
|
||||
/* extract the 'encryption' (could be signing) and hash oids from and
|
||||
* algorithm, key and parameters (parameters is the parameters field
|
||||
* of a algorithm ID structure (SECAlgorithmID)*/
|
||||
SECStatus sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
|
||||
const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _KEYHI_H_ */
|
|
@ -48,6 +48,7 @@
|
|||
#include "secdig.h"
|
||||
#include "prtime.h"
|
||||
#include "ec.h"
|
||||
#include "keyi.h"
|
||||
|
||||
const SEC_ASN1Template CERT_SubjectPublicKeyInfoTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
|
@ -939,13 +940,11 @@ done:
|
|||
}
|
||||
|
||||
|
||||
/* Function used to determine what kind of cert we are dealing with. */
|
||||
/* Function used to make an oid tag to a key type */
|
||||
KeyType
|
||||
CERT_GetCertKeyType (CERTSubjectPublicKeyInfo *spki) {
|
||||
int tag;
|
||||
seckey_GetKeyType (SECOidTag tag) {
|
||||
KeyType keyType;
|
||||
|
||||
tag = SECOID_GetAlgorithmTag(&spki->algorithm);
|
||||
switch (tag) {
|
||||
case SEC_OID_X500_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||
|
@ -976,6 +975,13 @@ CERT_GetCertKeyType (CERTSubjectPublicKeyInfo *spki) {
|
|||
return keyType;
|
||||
}
|
||||
|
||||
/* Function used to determine what kind of cert we are dealing with. */
|
||||
KeyType
|
||||
CERT_GetCertKeyType (CERTSubjectPublicKeyInfo *spki)
|
||||
{
|
||||
return seckey_GetKeyType(SECOID_GetAlgorithmTag(&spki->algorithm));
|
||||
}
|
||||
|
||||
static SECKEYPublicKey *
|
||||
seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
|
||||
{
|
||||
|
@ -1290,9 +1296,10 @@ SECKEY_ECParamsToKeySize(const SECItem *encodedParams)
|
|||
|
||||
/* returns key strength in bytes (not bits) */
|
||||
unsigned
|
||||
SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk)
|
||||
SECKEY_PublicKeyStrength(const SECKEYPublicKey *pubk)
|
||||
{
|
||||
unsigned char b0;
|
||||
unsigned size;
|
||||
|
||||
/* interpret modulus length as key strength... in
|
||||
* fortezza that's the public key length */
|
||||
|
@ -1313,11 +1320,8 @@ SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk)
|
|||
return PR_MAX(pubk->u.fortezza.KEAKey.len, pubk->u.fortezza.DSSKey.len);
|
||||
case ecKey:
|
||||
/* Get the key size in bits and adjust */
|
||||
if (pubk->u.ec.size == 0) {
|
||||
pubk->u.ec.size =
|
||||
SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
|
||||
}
|
||||
return (pubk->u.ec.size + 7)/8;
|
||||
size = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
|
||||
return (size + 7)/8;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1326,8 +1330,9 @@ SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk)
|
|||
|
||||
/* returns key strength in bits */
|
||||
unsigned
|
||||
SECKEY_PublicKeyStrengthInBits(SECKEYPublicKey *pubk)
|
||||
SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk)
|
||||
{
|
||||
unsigned size;
|
||||
switch (pubk->keyType) {
|
||||
case rsaKey:
|
||||
case dsaKey:
|
||||
|
@ -1335,11 +1340,8 @@ SECKEY_PublicKeyStrengthInBits(SECKEYPublicKey *pubk)
|
|||
case fortezzaKey:
|
||||
return SECKEY_PublicKeyStrength(pubk) * 8; /* 1 byte = 8 bits */
|
||||
case ecKey:
|
||||
if (pubk->u.ec.size == 0) {
|
||||
pubk->u.ec.size =
|
||||
SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
|
||||
}
|
||||
return pubk->u.ec.size;
|
||||
size = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
|
||||
return size;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1347,7 +1349,7 @@ SECKEY_PublicKeyStrengthInBits(SECKEYPublicKey *pubk)
|
|||
}
|
||||
|
||||
SECKEYPrivateKey *
|
||||
SECKEY_CopyPrivateKey(SECKEYPrivateKey *privk)
|
||||
SECKEY_CopyPrivateKey(const SECKEYPrivateKey *privk)
|
||||
{
|
||||
SECKEYPrivateKey *copyk;
|
||||
PRArenaPool *arena;
|
||||
|
@ -1393,7 +1395,7 @@ fail:
|
|||
}
|
||||
|
||||
SECKEYPublicKey *
|
||||
SECKEY_CopyPublicKey(SECKEYPublicKey *pubk)
|
||||
SECKEY_CopyPublicKey(const SECKEYPublicKey *pubk)
|
||||
{
|
||||
SECKEYPublicKey *copyk;
|
||||
PRArenaPool *arena;
|
||||
|
@ -1944,8 +1946,8 @@ SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge,
|
|||
/* check the signature */
|
||||
sig = sd.signature;
|
||||
DER_ConvertBitString(&sig);
|
||||
rv = VFY_VerifyData(sd.data.data, sd.data.len, pubKey, &sig,
|
||||
SECOID_GetAlgorithmTag(&(sd.signatureAlgorithm)), wincx);
|
||||
rv = VFY_VerifyDataWithAlgorithmID(sd.data.data, sd.data.len, pubKey, &sig,
|
||||
&(sd.signatureAlgorithm), NULL, wincx);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: secsign.c,v 1.14 2005-09-02 01:24:44 wtchang%redhat.com Exp $ */
|
||||
/* $Id: secsign.c,v 1.15 2006-02-08 06:14:07 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptohi.h"
|
||||
|
@ -48,6 +48,7 @@
|
|||
#include "secdig.h"
|
||||
#include "pk11func.h"
|
||||
#include "secerr.h"
|
||||
#include "keyi.h"
|
||||
|
||||
struct SGNContextStr {
|
||||
SECOidTag signalg;
|
||||
|
@ -63,6 +64,7 @@ SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key)
|
|||
SGNContext *cx;
|
||||
SECOidTag hashalg, signalg;
|
||||
KeyType keyType;
|
||||
SECStatus rv;
|
||||
|
||||
/* OK, map a PKCS #7 hash and encrypt algorithm into
|
||||
* a standard hashing algorithm. Why did we pass in the whole
|
||||
|
@ -71,68 +73,13 @@ SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key)
|
|||
* hashing on card. It may not support CKM_RSA_PKCS sign algorithm,
|
||||
* it may just support CKM_RSA_PKCS_WITH_SHA1 and/or CKM_RSA_PKCS_WITH_MD5.
|
||||
*/
|
||||
switch (alg) {
|
||||
/* We probably shouldn't be generating MD2 signatures either */
|
||||
case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
|
||||
hashalg = SEC_OID_MD2;
|
||||
signalg = SEC_OID_PKCS1_RSA_ENCRYPTION;
|
||||
keyType = rsaKey;
|
||||
break;
|
||||
case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
|
||||
hashalg = SEC_OID_MD5;
|
||||
signalg = SEC_OID_PKCS1_RSA_ENCRYPTION;
|
||||
keyType = rsaKey;
|
||||
break;
|
||||
case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
|
||||
hashalg = SEC_OID_SHA1;
|
||||
signalg = SEC_OID_PKCS1_RSA_ENCRYPTION;
|
||||
keyType = rsaKey;
|
||||
break;
|
||||
|
||||
case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
|
||||
hashalg = SEC_OID_SHA256;
|
||||
signalg = SEC_OID_PKCS1_RSA_ENCRYPTION;
|
||||
keyType = rsaKey;
|
||||
break;
|
||||
case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
|
||||
hashalg = SEC_OID_SHA384;
|
||||
signalg = SEC_OID_PKCS1_RSA_ENCRYPTION;
|
||||
keyType = rsaKey;
|
||||
break;
|
||||
case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
|
||||
hashalg = SEC_OID_SHA512;
|
||||
signalg = SEC_OID_PKCS1_RSA_ENCRYPTION;
|
||||
keyType = rsaKey;
|
||||
break;
|
||||
|
||||
/* what about normal DSA? */
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
hashalg = SEC_OID_SHA1;
|
||||
signalg = SEC_OID_ANSIX9_DSA_SIGNATURE;
|
||||
keyType = dsaKey;
|
||||
break;
|
||||
case SEC_OID_MISSI_DSS:
|
||||
case SEC_OID_MISSI_KEA_DSS:
|
||||
case SEC_OID_MISSI_KEA_DSS_OLD:
|
||||
case SEC_OID_MISSI_DSS_OLD:
|
||||
hashalg = SEC_OID_SHA1;
|
||||
signalg = SEC_OID_MISSI_DSS; /* XXX Is there a better algid? */
|
||||
keyType = fortezzaKey;
|
||||
break;
|
||||
case SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
hashalg = SEC_OID_SHA1;
|
||||
signalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
|
||||
keyType = ecKey;
|
||||
break;
|
||||
/* we don't implement MD4 hashes.
|
||||
* we *CERTAINLY* don't want to sign one! */
|
||||
case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
|
||||
default:
|
||||
/* we have a private key, not a public key, so don't pass it in */
|
||||
rv = sec_DecodeSigAlg(NULL, alg, NULL, &signalg, &hashalg);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
return 0;
|
||||
}
|
||||
keyType = seckey_GetKeyType(signalg);
|
||||
|
||||
/* verify our key type */
|
||||
if (key->keyType != keyType &&
|
||||
|
@ -503,9 +450,19 @@ SEC_GetSignatureAlgorithmOidTag(KeyType keyType, SECOidTag hashAlgTag)
|
|||
}
|
||||
break;
|
||||
case ecKey:
|
||||
/* XXX For now only ECDSA with SHA1 is supported */
|
||||
sigTag = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
|
||||
switch (hashAlgTag) {
|
||||
case SEC_OID_UNKNOWN: /* default for ECDSA if not specified */
|
||||
case SEC_OID_SHA1:
|
||||
sigTag = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; break;
|
||||
case SEC_OID_SHA256:
|
||||
sigTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; break;
|
||||
case SEC_OID_SHA384:
|
||||
sigTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; break;
|
||||
case SEC_OID_SHA512:
|
||||
sigTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: secvfy.c,v 1.16 2005-08-24 23:05:39 wtchang%redhat.com Exp $ */
|
||||
/* $Id: secvfy.c,v 1.17 2006-02-08 06:14:07 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptohi.h"
|
||||
|
@ -48,6 +48,7 @@
|
|||
#include "pk11func.h"
|
||||
#include "secdig.h"
|
||||
#include "secerr.h"
|
||||
#include "keyi.h"
|
||||
|
||||
/*
|
||||
** Decrypt signature block using public key
|
||||
|
@ -57,7 +58,7 @@
|
|||
*/
|
||||
static SECStatus
|
||||
DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, unsigned int len,
|
||||
SECKEYPublicKey *key, SECItem *sig, char *wincx)
|
||||
SECKEYPublicKey *key, const SECItem *sig, char *wincx)
|
||||
{
|
||||
SGNDigestInfo *di = NULL;
|
||||
unsigned char *buf = NULL;
|
||||
|
@ -73,7 +74,7 @@ DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, unsigned int len,
|
|||
if (!buf) goto loser;
|
||||
|
||||
/* decrypt the block */
|
||||
rv = PK11_VerifyRecover(key, sig, &it, wincx);
|
||||
rv = PK11_VerifyRecover(key, (SECItem *)sig, &it, wincx);
|
||||
if (rv != SECSuccess) goto loser;
|
||||
|
||||
di = SGN_DecodeDigestInfo(&it);
|
||||
|
@ -106,11 +107,10 @@ DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, unsigned int len,
|
|||
return rv;
|
||||
}
|
||||
|
||||
typedef enum { VFY_RSA, VFY_DSA, VFY_ECDSA } VerifyType;
|
||||
|
||||
struct VFYContextStr {
|
||||
SECOidTag alg; /* the hash algorithm */
|
||||
VerifyType type;
|
||||
KeyType type;
|
||||
SECKEYPublicKey *key;
|
||||
/*
|
||||
* This buffer holds either the digest or the full signature
|
||||
|
@ -134,7 +134,7 @@ struct VFYContextStr {
|
|||
void * wincx;
|
||||
void *hashcx;
|
||||
const SECHashObject *hashobj;
|
||||
SECOidTag sigAlg; /* the (composite) signature algorithm */
|
||||
SECOidTag encAlg; /* enc alg */
|
||||
PRBool hasSignature; /* true if the signature was provided in the
|
||||
* VFY_CreateContext call. If false, the
|
||||
* signature must be provided with a
|
||||
|
@ -147,39 +147,34 @@ struct VFYContextStr {
|
|||
* to by dsig and has enough room for len bytes.
|
||||
*/
|
||||
static SECStatus
|
||||
decodeECorDSASignature(SECOidTag algid, SECItem *sig, unsigned char *dsig,
|
||||
decodeECorDSASignature(SECOidTag algid, const SECItem *sig, unsigned char *dsig,
|
||||
unsigned int len) {
|
||||
SECItem *dsasig = NULL; /* also used for ECDSA */
|
||||
SECStatus rv=SECSuccess;
|
||||
|
||||
switch (algid) {
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||
case SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
if (algid == SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST) {
|
||||
if (len > MAX_ECKEY_LEN * 2) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return SECFailure;
|
||||
}
|
||||
dsasig = DSAU_DecodeDerSigToLen(sig, len);
|
||||
} else {
|
||||
dsasig = DSAU_DecodeDerSig(sig);
|
||||
}
|
||||
|
||||
if ((dsasig == NULL) || (dsasig->len != len)) {
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
PORT_Memcpy(dsig, dsasig->data, dsasig->len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ((algid != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
|
||||
(algid != SEC_OID_ANSIX962_EC_PUBLIC_KEY) ) {
|
||||
if (sig->len != len) {
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
PORT_Memcpy(dsig, sig->data, sig->len);
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Memcpy(dsig, sig->data, sig->len);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
if (algid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) {
|
||||
if (len > MAX_ECKEY_LEN * 2) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return SECFailure;
|
||||
}
|
||||
break;
|
||||
}
|
||||
dsasig = DSAU_DecodeDerSigToLen((SECItem *)sig, len);
|
||||
|
||||
if ((dsasig == NULL) || (dsasig->len != len)) {
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
PORT_Memcpy(dsig, dsasig->data, dsasig->len);
|
||||
}
|
||||
|
||||
if (dsasig != NULL) SECITEM_FreeItem(dsasig, PR_TRUE);
|
||||
|
@ -187,25 +182,38 @@ decodeECorDSASignature(SECOidTag algid, SECItem *sig, unsigned char *dsig,
|
|||
return rv;
|
||||
}
|
||||
|
||||
const SEC_ASN1Template hashParameterTemplate[] =
|
||||
{
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) },
|
||||
{ SEC_ASN1_OBJECT_ID, 0 },
|
||||
{ SEC_ASN1_SKIP_REST },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
/*
|
||||
* Pulls the hash algorithm, signing algorithm, and key type out of a
|
||||
* composite algorithm.
|
||||
*
|
||||
* alg: the composite algorithm to dissect.
|
||||
* hashalg: address of a SECOidTag which will be set with the hash algorithm.
|
||||
* signalg: address of a SECOidTag which will be set with the signing alg.
|
||||
* (not implemented)
|
||||
* keyType: address of a KeyType which will be set with the key type.
|
||||
* (not implemented)
|
||||
* encalg: address of a SECOidTag which will be set with the signing alg.
|
||||
*
|
||||
* Returns: SECSuccess if the algorithm was acceptable, SECFailure if the
|
||||
* algorithm was not found or was not a signing algorithm.
|
||||
*/
|
||||
static SECStatus
|
||||
decodeSigAlg(SECOidTag alg, SECOidTag *hashalg)
|
||||
SECStatus
|
||||
sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
|
||||
const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg)
|
||||
{
|
||||
PR_ASSERT(hashalg!=NULL);
|
||||
int len;
|
||||
PRArenaPool *arena;
|
||||
SECStatus rv;
|
||||
SECItem oid;
|
||||
|
||||
switch (alg) {
|
||||
PR_ASSERT(hashalg!=NULL);
|
||||
PR_ASSERT(encalg!=NULL);
|
||||
|
||||
switch (sigAlg) {
|
||||
/* We probably shouldn't be generating MD2 signatures either */
|
||||
case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
|
||||
*hashalg = SEC_OID_MD2;
|
||||
|
@ -217,13 +225,19 @@ decodeSigAlg(SECOidTag alg, SECOidTag *hashalg)
|
|||
case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
|
||||
*hashalg = SEC_OID_SHA1;
|
||||
break;
|
||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||
*hashalg = SEC_OID_UNKNOWN; /* get it from the RSA signature */
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
|
||||
case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
|
||||
*hashalg = SEC_OID_SHA256;
|
||||
break;
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
|
||||
case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
|
||||
*hashalg = SEC_OID_SHA384;
|
||||
break;
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
|
||||
case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
|
||||
*hashalg = SEC_OID_SHA512;
|
||||
break;
|
||||
|
@ -231,7 +245,7 @@ decodeSigAlg(SECOidTag alg, SECOidTag *hashalg)
|
|||
/* what about normal DSA? */
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
case SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
|
||||
*hashalg = SEC_OID_SHA1;
|
||||
break;
|
||||
case SEC_OID_MISSI_DSS:
|
||||
|
@ -240,85 +254,217 @@ decodeSigAlg(SECOidTag alg, SECOidTag *hashalg)
|
|||
case SEC_OID_MISSI_DSS_OLD:
|
||||
*hashalg = SEC_OID_SHA1;
|
||||
break;
|
||||
case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
|
||||
/* This is an EC algorithm. Recommended means the largest
|
||||
* hash algorithm that is not reduced by the keysize of
|
||||
* the EC algorithm. Note that key strength is in bytes and
|
||||
* algorithms are specified in bits. Never use an algorithm
|
||||
* weaker than sha1. */
|
||||
len = SECKEY_PublicKeyStrength(key);
|
||||
if (len < 28) { /* 28 bytes == 224 bits */
|
||||
*hashalg = SEC_OID_SHA1;
|
||||
} else if (len < 32) { /* 32 bytes == 256 bits */
|
||||
/* SHA 224 not supported in NSS */
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
return SECFailure;
|
||||
} else if (len < 48) { /* 48 bytes == 384 bits */
|
||||
*hashalg = SEC_OID_SHA256;
|
||||
} else if (len < 64) { /* 48 bytes == 512 bits */
|
||||
*hashalg = SEC_OID_SHA384;
|
||||
} else {
|
||||
/* use the largest in this case */
|
||||
*hashalg = SEC_OID_SHA512;
|
||||
}
|
||||
break;
|
||||
case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
|
||||
if (param == NULL) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
return SECFailure;
|
||||
}
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (arena == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
rv = SEC_QuickDERDecodeItem(arena, &oid, hashParameterTemplate, param);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
*hashalg = SECOID_FindOIDTag(&oid);
|
||||
/* only accept hash algorithms */
|
||||
if (HASH_GetHashTypeByOidTag(*hashalg) == HASH_AlgNULL) {
|
||||
/* error set by HASH_GetHashTypeByOidTag */
|
||||
return SECFailure;
|
||||
}
|
||||
break;
|
||||
/* we don't implement MD4 hashes */
|
||||
case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
return SECFailure;
|
||||
}
|
||||
/* get the "encryption" algorithm */
|
||||
switch (sigAlg) {
|
||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
|
||||
case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
|
||||
*encalg = SEC_OID_PKCS1_RSA_ENCRYPTION;
|
||||
break;
|
||||
|
||||
/* what about normal DSA? */
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
*encalg = SEC_OID_ANSIX9_DSA_SIGNATURE;
|
||||
break;
|
||||
case SEC_OID_MISSI_DSS:
|
||||
case SEC_OID_MISSI_KEA_DSS:
|
||||
case SEC_OID_MISSI_KEA_DSS_OLD:
|
||||
case SEC_OID_MISSI_DSS_OLD:
|
||||
*encalg = SEC_OID_MISSI_DSS;
|
||||
break;
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
|
||||
case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
|
||||
case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
|
||||
*encalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
|
||||
break;
|
||||
/* we don't implement MD4 hashes */
|
||||
case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
VFYContext *
|
||||
VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid,
|
||||
void *wincx)
|
||||
/*
|
||||
* we can verify signatures that come from 2 different sources:
|
||||
* one in with the signature contains a signature oid, and the other
|
||||
* in which the signature is managed by a Public key (encAlg) oid
|
||||
* and a hash oid. The latter is the more basic, so that's what
|
||||
* our base vfyCreate function takes.
|
||||
*
|
||||
* There is one noteworthy corner case, if we are using an RSA key, and the
|
||||
* signature block is provided, then the hashAlg can be specified as
|
||||
* SEC_OID_UNKNOWN. In this case, verify will use the hash oid supplied
|
||||
* in the RSA signature block.
|
||||
*/
|
||||
static VFYContext *
|
||||
vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig,
|
||||
SECOidTag encAlg, SECOidTag hashAlg, SECOidTag *hash, void *wincx)
|
||||
{
|
||||
VFYContext *cx;
|
||||
SECStatus rv;
|
||||
unsigned int sigLen;
|
||||
SECOidTag hashid = SEC_OID_UNKNOWN;
|
||||
KeyType type;
|
||||
|
||||
/* make sure the encryption algorithm matches the key type */
|
||||
type = seckey_GetKeyType(encAlg);
|
||||
if (key->keyType != type) {
|
||||
PORT_SetError(SEC_ERROR_PKCS7_KEYALG_MISMATCH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cx = (VFYContext*) PORT_ZAlloc(sizeof(VFYContext));
|
||||
if (cx) {
|
||||
cx->wincx = wincx;
|
||||
cx->hasSignature = (sig != NULL);
|
||||
cx->sigAlg = algid;
|
||||
rv = SECSuccess;
|
||||
if (cx == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
cx->wincx = wincx;
|
||||
cx->hasSignature = (sig != NULL);
|
||||
cx->encAlg = encAlg;
|
||||
cx->alg = hashAlg;
|
||||
cx->key = SECKEY_CopyPublicKey(key);
|
||||
cx->type = key->keyType;
|
||||
rv = SECSuccess;
|
||||
if (sig) {
|
||||
switch (key->keyType) {
|
||||
case rsaKey:
|
||||
cx->type = VFY_RSA;
|
||||
cx->key = SECKEY_CopyPublicKey(key); /* extra safety precautions */
|
||||
if (sig) {
|
||||
SECOidTag hashid = SEC_OID_UNKNOWN;
|
||||
rv = DecryptSigBlock(&hashid, cx->u.buffer,
|
||||
rv = DecryptSigBlock(&hashid, cx->u.buffer,
|
||||
HASH_LENGTH_MAX, cx->key, sig, (char*)wincx);
|
||||
cx->alg = hashid;
|
||||
} else {
|
||||
rv = decodeSigAlg(algid,&cx->alg);
|
||||
if (cx->alg != SEC_OID_UNKNOWN && cx->alg != hashid) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
cx->alg = hashid;
|
||||
break;
|
||||
case fortezzaKey:
|
||||
case dsaKey:
|
||||
case ecKey:
|
||||
if (key->keyType == ecKey) {
|
||||
cx->type = VFY_ECDSA;
|
||||
/* Unlike DSA, EDSA does not have a fixed signature length
|
||||
* (it depends on the key size)
|
||||
*/
|
||||
sigLen = SECKEY_PublicKeyStrength(key) * 2;
|
||||
} else {
|
||||
cx->type = VFY_DSA;
|
||||
sigLen = DSA_SIGNATURE_LEN;
|
||||
}
|
||||
cx->alg = SEC_OID_SHA1;
|
||||
cx->key = SECKEY_CopyPublicKey(key);
|
||||
if (sig) {
|
||||
rv = decodeECorDSASignature(algid,sig,cx->u.buffer,sigLen);
|
||||
}
|
||||
break;
|
||||
sigLen = (key->keyType == ecKey) ?
|
||||
SECKEY_PublicKeyStrength(key) * 2 :
|
||||
DSA_SIGNATURE_LEN;
|
||||
rv = decodeECorDSASignature(encAlg, sig, cx->u.buffer, sigLen);
|
||||
break;
|
||||
default:
|
||||
rv = SECFailure;
|
||||
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
|
||||
break;
|
||||
}
|
||||
if (rv) goto loser;
|
||||
switch (cx->alg) {
|
||||
case SEC_OID_MD2:
|
||||
case SEC_OID_MD5:
|
||||
case SEC_OID_SHA1:
|
||||
case SEC_OID_SHA256:
|
||||
case SEC_OID_SHA384:
|
||||
case SEC_OID_SHA512:
|
||||
break;
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
if (rv) goto loser;
|
||||
|
||||
/* check hash alg again, RSA may have changed it.*/
|
||||
if (HASH_GetHashTypeByOidTag(cx->alg) == HASH_AlgNULL) {
|
||||
/* error set by HASH_GetHashTypeByOidTag */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hash) {
|
||||
*hash = cx->alg;
|
||||
}
|
||||
return cx;
|
||||
|
||||
loser:
|
||||
VFY_DestroyContext(cx, PR_TRUE);
|
||||
if (cx) {
|
||||
VFY_DestroyContext(cx, PR_TRUE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
VFYContext *
|
||||
VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag sigAlg,
|
||||
void *wincx)
|
||||
{
|
||||
SECOidTag encAlg, hashAlg;
|
||||
SECStatus rv = sec_DecodeSigAlg(key, sigAlg, NULL, &encAlg, &hashAlg);
|
||||
if (rv != SECSuccess) {
|
||||
return NULL;
|
||||
}
|
||||
return vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx);
|
||||
}
|
||||
|
||||
VFYContext *
|
||||
VFY_CreateContextDirect(const SECKEYPublicKey *key, const SECItem *sig,
|
||||
SECOidTag encAlg, SECOidTag hashAlg,
|
||||
SECOidTag *hash, void *wincx)
|
||||
{
|
||||
return vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
|
||||
}
|
||||
|
||||
VFYContext *
|
||||
VFY_CreateContextWithAlgorithmID(const SECKEYPublicKey *key, const SECItem *sig,
|
||||
const SECAlgorithmID *sigAlgorithm, SECOidTag *hash, void *wincx)
|
||||
{
|
||||
SECOidTag encAlg, hashAlg;
|
||||
SECStatus rv = sec_DecodeSigAlg(key,
|
||||
SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm),
|
||||
&sigAlgorithm->parameters, &encAlg, &hashAlg);
|
||||
if (rv != SECSuccess) {
|
||||
return NULL;
|
||||
}
|
||||
return vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
|
||||
}
|
||||
|
||||
void
|
||||
VFY_DestroyContext(VFYContext *cx, PRBool freeit)
|
||||
{
|
||||
|
@ -357,7 +503,7 @@ VFY_Begin(VFYContext *cx)
|
|||
}
|
||||
|
||||
SECStatus
|
||||
VFY_Update(VFYContext *cx, unsigned char *input, unsigned inputLen)
|
||||
VFY_Update(VFYContext *cx, const unsigned char *input, unsigned inputLen)
|
||||
{
|
||||
if (cx->hashcx == NULL) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
|
@ -386,16 +532,14 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
|
|||
}
|
||||
(*cx->hashobj->end)(cx->hashcx, final, &part, sizeof(final));
|
||||
switch (cx->type) {
|
||||
case VFY_DSA:
|
||||
case VFY_ECDSA:
|
||||
case ecKey:
|
||||
case dsaKey:
|
||||
dsasig.data = cx->u.buffer;
|
||||
if (cx->type == VFY_DSA) {
|
||||
dsasig.len = DSA_SIGNATURE_LEN;
|
||||
} else {
|
||||
dsasig.len = SECKEY_PublicKeyStrength(cx->key) * 2;
|
||||
}
|
||||
dsasig.len = (cx->type == ecKey) ?
|
||||
SECKEY_PublicKeyStrength(cx->key) * 2 :
|
||||
DSA_SIGNATURE_LEN;
|
||||
if (sig) {
|
||||
rv = decodeECorDSASignature(cx->sigAlg,sig,dsasig.data,
|
||||
rv = decodeECorDSASignature(cx->encAlg, sig, dsasig.data,
|
||||
dsasig.len);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
|
@ -409,7 +553,7 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
|
|||
return SECFailure;
|
||||
}
|
||||
break;
|
||||
case VFY_RSA:
|
||||
case rsaKey:
|
||||
if (sig) {
|
||||
SECOidTag hashid = SEC_OID_UNKNOWN;
|
||||
rv = DecryptSigBlock(&hashid, cx->u.buffer,
|
||||
|
@ -440,13 +584,11 @@ VFY_End(VFYContext *cx)
|
|||
/************************************************************************/
|
||||
/*
|
||||
* Verify that a previously-computed digest matches a signature.
|
||||
* XXX This should take a parameter that specifies the digest algorithm,
|
||||
* and we should compare that the algorithm found in the DigestInfo
|
||||
* matches it!
|
||||
*/
|
||||
SECStatus
|
||||
VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig,
|
||||
SECOidTag algid, void *wincx)
|
||||
static SECStatus
|
||||
vfy_VerifyDigest(const SECItem *digest, const SECKEYPublicKey *key,
|
||||
const SECItem *sig, SECOidTag encAlg, SECOidTag hashAlg,
|
||||
void *wincx)
|
||||
{
|
||||
SECStatus rv;
|
||||
VFYContext *cx;
|
||||
|
@ -454,7 +596,7 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig,
|
|||
|
||||
rv = SECFailure;
|
||||
|
||||
cx = VFY_CreateContext(key, sig, algid, wincx);
|
||||
cx = vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx);
|
||||
if (cx != NULL) {
|
||||
switch (key->keyType) {
|
||||
case rsaKey:
|
||||
|
@ -464,7 +606,6 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig,
|
|||
rv = SECSuccess;
|
||||
}
|
||||
break;
|
||||
case fortezzaKey:
|
||||
case dsaKey:
|
||||
case ecKey:
|
||||
dsasig.data = cx->u.buffer;
|
||||
|
@ -474,7 +615,7 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig,
|
|||
/* magic size of dsa signature */
|
||||
dsasig.len = DSA_SIGNATURE_LEN;
|
||||
}
|
||||
if (PK11_Verify(cx->key, &dsasig, digest, cx->wincx)
|
||||
if (PK11_Verify(cx->key, &dsasig, (SECItem *)digest, cx->wincx)
|
||||
!= SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
} else {
|
||||
|
@ -490,19 +631,66 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig,
|
|||
}
|
||||
|
||||
SECStatus
|
||||
VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key,
|
||||
SECItem *sig, SECOidTag algid, void *wincx)
|
||||
VFY_VerifyDigestDirect(const SECItem *digest, const SECKEYPublicKey *key,
|
||||
const SECItem *sig, SECOidTag encAlg,
|
||||
SECOidTag hashAlg, void *wincx)
|
||||
{
|
||||
return VFY_VerifyDigestDirect(digest, key, sig, encAlg, hashAlg, wincx);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig,
|
||||
SECOidTag algid, void *wincx)
|
||||
{
|
||||
SECOidTag encAlg, hashAlg;
|
||||
SECStatus rv = sec_DecodeSigAlg(key, algid, NULL, &encAlg, &hashAlg);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
return vfy_VerifyDigest(digest, key, sig, encAlg, hashAlg, wincx);
|
||||
}
|
||||
|
||||
/*
|
||||
* this function takes an optional hash oid, which the digest function
|
||||
* will be compared with our target hash value.
|
||||
*/
|
||||
SECStatus
|
||||
VFY_VerifyDigestWithAlgorithmID(const SECItem *digest,
|
||||
const SECKEYPublicKey *key, const SECItem *sig,
|
||||
const SECAlgorithmID *sigAlgorithm,
|
||||
SECOidTag hashCmp, void *wincx)
|
||||
{
|
||||
SECOidTag encAlg, hashAlg;
|
||||
SECStatus rv = sec_DecodeSigAlg(key,
|
||||
SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm),
|
||||
&sigAlgorithm->parameters, &encAlg, &hashAlg);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
if ( hashCmp != SEC_OID_UNKNOWN &&
|
||||
hashAlg != SEC_OID_UNKNOWN &&
|
||||
hashCmp != hashAlg) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
return SECFailure;
|
||||
}
|
||||
return vfy_VerifyDigest(digest, key, sig, encAlg, hashAlg, wincx);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
vfy_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key,
|
||||
const SECItem *sig, SECOidTag encAlg, SECOidTag hashAlg,
|
||||
SECOidTag *hash, void *wincx)
|
||||
{
|
||||
SECStatus rv;
|
||||
VFYContext *cx;
|
||||
|
||||
cx = VFY_CreateContext(key, sig, algid, wincx);
|
||||
cx = vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
|
||||
if (cx == NULL)
|
||||
return SECFailure;
|
||||
|
||||
rv = VFY_Begin(cx);
|
||||
if (rv == SECSuccess) {
|
||||
rv = VFY_Update(cx, buf, len);
|
||||
rv = VFY_Update(cx, (unsigned char *)buf, len);
|
||||
if (rv == SECSuccess)
|
||||
rv = VFY_End(cx);
|
||||
}
|
||||
|
@ -510,3 +698,41 @@ VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key,
|
|||
VFY_DestroyContext(cx, PR_TRUE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
VFY_VerifyDataDirect(const unsigned char *buf, int len,
|
||||
const SECKEYPublicKey *key, const SECItem *sig,
|
||||
SECOidTag encAlg, SECOidTag hashAlg,
|
||||
SECOidTag *hash, void *wincx)
|
||||
{
|
||||
return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key,
|
||||
SECItem *sig, SECOidTag algid, void *wincx)
|
||||
{
|
||||
SECOidTag encAlg, hashAlg;
|
||||
SECStatus rv = sec_DecodeSigAlg(key, algid, NULL, &encAlg, &hashAlg);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, NULL, wincx);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
VFY_VerifyDataWithAlgorithmID(const unsigned char *buf, int len,
|
||||
const SECKEYPublicKey *key,
|
||||
const SECItem *sig,
|
||||
const SECAlgorithmID *sigAlgorithm,
|
||||
SECOidTag *hash, void *wincx)
|
||||
{
|
||||
SECOidTag encAlg, hashAlg;
|
||||
SECStatus rv = sec_DecodeSigAlg(key,
|
||||
SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm),
|
||||
&sigAlgorithm->parameters, &encAlg, &hashAlg);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx);
|
||||
}
|
||||
|
|
|
@ -875,6 +875,12 @@ SECMOD_OpenUserDB;
|
|||
;+NSS_3.12 { # NSS 3.12 release
|
||||
;+ global:
|
||||
PK11_GetAllSlotsForCert;
|
||||
VFY_CreateContextDirect;
|
||||
VFY_CreateContextWithAlgorithmID;
|
||||
VFY_VerifyDataDirect;
|
||||
VFY_VerifyDataWithAlgorithmID;
|
||||
VFY_VerifyDigestDirect;
|
||||
VFY_VerifyDigestWithAlgorithmID;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
/*
|
||||
* PKCS7 decoding, verification.
|
||||
*
|
||||
* $Id: p7decode.c,v 1.20 2005-10-03 22:01:56 relyea%netscape.com Exp $
|
||||
* $Id: p7decode.c,v 1.21 2006-02-08 06:14:18 rrelyea%redhat.com Exp $
|
||||
*/
|
||||
|
||||
#include "nssrenam.h"
|
||||
|
@ -1436,7 +1436,8 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
|
|||
CERTCertificate *cert, **certs;
|
||||
PRBool goodsig;
|
||||
CERTCertDBHandle *certdb, *defaultdb;
|
||||
SECOidData *algiddata;
|
||||
SECOidTag encTag,digestTag;
|
||||
HASH_HashType found_type;
|
||||
int i, certcount;
|
||||
SECKEYPublicKey *publickey;
|
||||
SECItem *content_type;
|
||||
|
@ -1615,14 +1616,19 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
|
|||
/*
|
||||
* Find and confirm digest algorithm.
|
||||
*/
|
||||
algiddata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
|
||||
digestTag = SECOID_FindOIDTag(&(signerinfo->digestAlg.algorithm));
|
||||
|
||||
/* make sure we understand the digest type first */
|
||||
found_type = HASH_GetHashTypeByOidTag(digestTag);
|
||||
if ((digestTag == SEC_OID_UNKNOWN) || (found_type == HASH_AlgNULL)) {
|
||||
PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (detached_digest != NULL) {
|
||||
HASH_HashType found_type = HASH_GetHashTypeByOidTag(algiddata->offset);
|
||||
unsigned int hashLen = HASH_ResultLen(digest_type);
|
||||
unsigned int hashLen = HASH_ResultLen(found_type);
|
||||
|
||||
if (digest_type != found_type ||
|
||||
digest_type == HASH_AlgNULL ||
|
||||
detached_digest->len != hashLen) {
|
||||
PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
|
||||
goto done;
|
||||
|
@ -1638,12 +1644,8 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
|
|||
/*
|
||||
* pick digest matching signerinfo->digestAlg from digests
|
||||
*/
|
||||
if (algiddata == NULL) {
|
||||
PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
for (i = 0; digestalgs[i] != NULL; i++) {
|
||||
if (SECOID_FindOID (&(digestalgs[i]->algorithm)) == algiddata)
|
||||
if (SECOID_FindOIDTag(&(digestalgs[i]->algorithm)) == digestTag)
|
||||
break;
|
||||
}
|
||||
if (digestalgs[i] == NULL) {
|
||||
|
@ -1654,19 +1656,8 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
|
|||
digest = digests[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX This may not be the right set of algorithms to check.
|
||||
* I'd prefer to trust that just calling VFY_Verify{Data,Digest}
|
||||
* would do the right thing (and set an error if it could not);
|
||||
* then additional algorithms could be handled by that code
|
||||
* and we would Just Work. So this check should just be removed,
|
||||
* but not until the VFY code is better at setting errors.
|
||||
*/
|
||||
algiddata = SECOID_FindOID (&(signerinfo->digestEncAlg.algorithm));
|
||||
if (algiddata == NULL ||
|
||||
((algiddata->offset != SEC_OID_PKCS1_RSA_ENCRYPTION) &&
|
||||
(algiddata->offset != SEC_OID_ANSIX962_EC_PUBLIC_KEY) &&
|
||||
(algiddata->offset != SEC_OID_ANSIX9_DSA_SIGNATURE))) {
|
||||
encTag = SECOID_FindOIDTag(&(signerinfo->digestEncAlg.algorithm));
|
||||
if (encTag == SEC_OID_UNKNOWN) {
|
||||
PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
|
@ -1735,14 +1726,10 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX the 5th (algid) argument should be the signature algorithm.
|
||||
* See sec_pkcs7_pick_sign_alg in p7encode.c.
|
||||
*/
|
||||
goodsig = (PRBool)(VFY_VerifyData (encoded_attrs.data,
|
||||
goodsig = (PRBool)(VFY_VerifyDataDirect(encoded_attrs.data,
|
||||
encoded_attrs.len,
|
||||
publickey, &(signerinfo->encDigest),
|
||||
SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg)),
|
||||
encTag, digestTag, NULL,
|
||||
cinfo->pwfn_arg) == SECSuccess);
|
||||
PORT_Free (encoded_attrs.data);
|
||||
} else {
|
||||
|
@ -1797,14 +1784,9 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
|
|||
sig = &holder;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX the 4th (algid) argument should be the signature algorithm.
|
||||
* See sec_pkcs7_pick_sign_alg in p7encode.c.
|
||||
*/
|
||||
goodsig = (PRBool)(VFY_VerifyDigest (digest, publickey, sig,
|
||||
SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg)),
|
||||
cinfo->pwfn_arg)
|
||||
== SECSuccess);
|
||||
goodsig = (PRBool)(VFY_VerifyDigestDirect(digest, publickey, sig,
|
||||
encTag, digestTag, cinfo->pwfn_arg)
|
||||
== SECSuccess);
|
||||
|
||||
if (sigkey != NULL) {
|
||||
PORT_Assert (sig == &holder);
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
/*
|
||||
* PKCS7 encoding.
|
||||
*
|
||||
* $Id: p7encode.c,v 1.11 2005-09-02 01:24:56 wtchang%redhat.com Exp $
|
||||
* $Id: p7encode.c,v 1.12 2006-02-08 06:14:19 rrelyea%redhat.com Exp $
|
||||
*/
|
||||
|
||||
#include "nssrenam.h"
|
||||
|
@ -835,56 +835,6 @@ SEC_PKCS7EncoderUpdate (SEC_PKCS7EncoderContext *p7ecx,
|
|||
PR_FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* XXX I would *really* like to not have to do this, but the current
|
||||
* signing interface gives me little choice.
|
||||
*/
|
||||
static SECOidTag
|
||||
sec_pkcs7_pick_sign_alg (SECOidTag hashalg, SECOidTag encalg)
|
||||
{
|
||||
switch (encalg) {
|
||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||
switch (hashalg) {
|
||||
case SEC_OID_MD2:
|
||||
return SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;
|
||||
case SEC_OID_MD5:
|
||||
return SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
|
||||
case SEC_OID_SHA1:
|
||||
return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
|
||||
case SEC_OID_SHA256:
|
||||
return SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
|
||||
case SEC_OID_SHA384:
|
||||
return SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
|
||||
case SEC_OID_SHA512:
|
||||
return SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
|
||||
default:
|
||||
return SEC_OID_UNKNOWN;
|
||||
}
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||
case SEC_OID_MISSI_KEA_DSS:
|
||||
case SEC_OID_MISSI_DSS:
|
||||
switch (hashalg) {
|
||||
case SEC_OID_SHA1:
|
||||
return SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
|
||||
default:
|
||||
return SEC_OID_UNKNOWN;
|
||||
}
|
||||
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
|
||||
switch (hashalg) {
|
||||
case SEC_OID_SHA1:
|
||||
return SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
|
||||
default:
|
||||
return SEC_OID_UNKNOWN;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return encalg; /* maybe it is already the right algid */
|
||||
}
|
||||
|
||||
|
||||
static SECStatus
|
||||
sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo,
|
||||
SECKEYGetPasswordKey pwfn, void *pwfnarg)
|
||||
|
@ -1000,6 +950,7 @@ sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo,
|
|||
SEC_PKCS7Attribute *attr;
|
||||
SECItem encoded_attrs;
|
||||
SECItem *dummy;
|
||||
SECOidTag algid;
|
||||
|
||||
/*
|
||||
* First, find and fill in the message digest attribute.
|
||||
|
@ -1050,11 +1001,17 @@ sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo,
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
algid = SEC_GetSignatureAlgorithmOidTag(privkey->keyType,
|
||||
digestalgtag);
|
||||
if (algid == SEC_OID_UNKNOWN) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
SECKEY_DestroyPrivateKey (privkey);
|
||||
return SECFailure;
|
||||
}
|
||||
rv = SEC_SignData (&signature,
|
||||
encoded_attrs.data, encoded_attrs.len,
|
||||
privkey,
|
||||
sec_pkcs7_pick_sign_alg (digestalgtag,
|
||||
signalgtag));
|
||||
algid);
|
||||
SECITEM_FreeItem (&encoded_attrs, PR_FALSE);
|
||||
} else {
|
||||
rv = SGN_Digest (privkey, digestalgtag, &signature,
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
/*
|
||||
* Interfaces of the CMS implementation.
|
||||
*
|
||||
* $Id: cms.h,v 1.20 2004-04-25 15:03:15 gerv%gerv.net Exp $
|
||||
* $Id: cms.h,v 1.21 2006-02-08 06:13:43 rrelyea%redhat.com Exp $
|
||||
*/
|
||||
|
||||
#ifndef _CMS_H_
|
||||
|
@ -410,13 +410,6 @@ NSS_CMSAlgArray_GetIndexByAlgTag(SECAlgorithmID **algorithmArray, SECOidTag algt
|
|||
extern const SECHashObject *
|
||||
NSS_CMSUtil_GetHashObjByAlgID(SECAlgorithmID *algid);
|
||||
|
||||
/*
|
||||
* XXX I would *really* like to not have to do this, but the current
|
||||
* signing interface gives me little choice.
|
||||
*/
|
||||
extern SECOidTag
|
||||
NSS_CMSUtil_MakeSignatureAlgorithm(SECOidTag hashalg, SECOidTag encalg);
|
||||
|
||||
extern const SEC_ASN1Template *
|
||||
NSS_CMSUtil_GetTemplateByTypeTag(SECOidTag type);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
/*
|
||||
* CMS signerInfo methods.
|
||||
*
|
||||
* $Id: cmssiginfo.c,v 1.29 2005-09-02 01:24:56 wtchang%redhat.com Exp $
|
||||
* $Id: cmssiginfo.c,v 1.30 2006-02-08 06:13:43 rrelyea%redhat.com Exp $
|
||||
*/
|
||||
|
||||
#include "cmslocal.h"
|
||||
|
@ -262,7 +262,13 @@ NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *c
|
|||
&encoded_attrs) == NULL)
|
||||
goto loser;
|
||||
|
||||
signAlgTag = NSS_CMSUtil_MakeSignatureAlgorithm(digestalgtag, pubkAlgTag);
|
||||
signAlgTag = SEC_GetSignatureAlgorithmOidTag(privkey->keyType,
|
||||
digestalgtag);
|
||||
if (signAlgTag == SEC_OID_UNKNOWN) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = SEC_SignData(&signature, encoded_attrs.data, encoded_attrs.len,
|
||||
privkey, signAlgTag);
|
||||
PORT_FreeArena(tmppoolp, PR_FALSE); /* awkward memory management :-( */
|
||||
|
@ -350,7 +356,6 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
|
|||
PLArenaPool *poolp;
|
||||
SECOidTag digestalgtag;
|
||||
SECOidTag pubkAlgTag;
|
||||
SECOidTag signAlgTag;
|
||||
|
||||
if (signerinfo == NULL)
|
||||
return SECFailure;
|
||||
|
@ -370,35 +375,12 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
|
|||
}
|
||||
|
||||
digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
|
||||
|
||||
/*
|
||||
* XXX This may not be the right set of algorithms to check.
|
||||
* I'd prefer to trust that just calling VFY_Verify{Data,Digest}
|
||||
* would do the right thing (and set an error if it could not);
|
||||
* then additional algorithms could be handled by that code
|
||||
* and we would Just Work. So this check should just be removed,
|
||||
* but not until the VFY code is better at setting errors.
|
||||
*/
|
||||
pubkAlgTag = SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg));
|
||||
switch (pubkAlgTag) {
|
||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
|
||||
/* ok */
|
||||
break;
|
||||
case SEC_OID_UNKNOWN:
|
||||
if ((pubkAlgTag == SEC_OID_UNKNOWN) || (digestalgtag == SEC_OID_UNKNOWN)) {
|
||||
vs = NSSCMSVS_SignatureAlgorithmUnknown;
|
||||
goto loser;
|
||||
default:
|
||||
vs = NSSCMSVS_SignatureAlgorithmUnsupported;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
signAlgTag = NSS_CMSUtil_MakeSignatureAlgorithm(digestalgtag, pubkAlgTag);
|
||||
|
||||
if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) {
|
||||
if (contentType) {
|
||||
/*
|
||||
|
@ -461,10 +443,10 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
|
|||
goto loser;
|
||||
}
|
||||
|
||||
vs = (VFY_VerifyData (encoded_attrs.data, encoded_attrs.len,
|
||||
publickey, &(signerinfo->encDigest), signAlgTag,
|
||||
signerinfo->cmsg->pwfn_arg) != SECSuccess)
|
||||
? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
|
||||
vs = (VFY_VerifyDataDirect(encoded_attrs.data, encoded_attrs.len,
|
||||
publickey, &(signerinfo->encDigest), pubkAlgTag,
|
||||
digestalgtag, NULL, signerinfo->cmsg->pwfn_arg) != SECSuccess)
|
||||
? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
|
||||
|
||||
PORT_FreeArena(poolp, PR_FALSE); /* awkward memory management :-( */
|
||||
|
||||
|
@ -479,16 +461,17 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
|
|||
goto loser;
|
||||
|
||||
vs = (!digest ||
|
||||
VFY_VerifyDigest(digest, publickey, sig, signAlgTag,
|
||||
signerinfo->cmsg->pwfn_arg) != SECSuccess)
|
||||
? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
|
||||
VFY_VerifyDigestDirect(digest, publickey, sig, pubkAlgTag,
|
||||
digestalgtag, signerinfo->cmsg->pwfn_arg) != SECSuccess)
|
||||
? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
|
||||
}
|
||||
|
||||
if (vs == NSSCMSVS_BadSignature) {
|
||||
int error = PORT_GetError();
|
||||
/*
|
||||
* XXX Change the generic error into our specific one, because
|
||||
* in that case we get a better explanation out of the Security
|
||||
* Advisor. This is really a bug in our error strings (the
|
||||
* Advisor. This is really a bug in the PSM error strings (the
|
||||
* "generic" error has a lousy/wrong message associated with it
|
||||
* which assumes the signature verification was done for the
|
||||
* purposes of checking the issuer signature on a certificate)
|
||||
|
@ -501,8 +484,17 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
|
|||
* certificate signature check that failed during the cert
|
||||
* verification done above. Our error handling is really a mess.
|
||||
*/
|
||||
if (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE)
|
||||
if (error == SEC_ERROR_BAD_SIGNATURE)
|
||||
PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
|
||||
/*
|
||||
* map algorithm failures to NSSCMSVS values
|
||||
*/
|
||||
if ((error == SEC_ERROR_PKCS7_KEYALG_MISMATCH) ||
|
||||
(error == SEC_ERROR_INVALID_ALGORITHM)) {
|
||||
/* keep the same error code as 3.11 and before */
|
||||
PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
|
||||
vs = NSSCMSVS_SignatureAlgorithmUnsupported;
|
||||
}
|
||||
}
|
||||
|
||||
if (publickey != NULL)
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
/*
|
||||
* CMS miscellaneous utility functions.
|
||||
*
|
||||
* $Id: cmsutil.c,v 1.13 2005-09-02 01:24:56 wtchang%redhat.com Exp $
|
||||
* $Id: cmsutil.c,v 1.14 2006-02-08 06:13:43 rrelyea%redhat.com Exp $
|
||||
*/
|
||||
|
||||
#include "nssrenam.h"
|
||||
|
@ -222,54 +222,6 @@ NSS_CMSUtil_GetHashObjByAlgID(SECAlgorithmID *algid)
|
|||
return digobj;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX I would *really* like to not have to do this, but the current
|
||||
* signing interface gives me little choice.
|
||||
*/
|
||||
SECOidTag
|
||||
NSS_CMSUtil_MakeSignatureAlgorithm(SECOidTag hashalg, SECOidTag encalg)
|
||||
{
|
||||
switch (encalg) {
|
||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||
switch (hashalg) {
|
||||
case SEC_OID_MD2:
|
||||
return SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;
|
||||
case SEC_OID_MD5:
|
||||
return SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
|
||||
case SEC_OID_SHA1:
|
||||
return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
|
||||
case SEC_OID_SHA256:
|
||||
return SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
|
||||
case SEC_OID_SHA384:
|
||||
return SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
|
||||
case SEC_OID_SHA512:
|
||||
return SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
|
||||
default:
|
||||
return SEC_OID_UNKNOWN;
|
||||
}
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||
case SEC_OID_MISSI_KEA_DSS:
|
||||
case SEC_OID_MISSI_DSS:
|
||||
switch (hashalg) {
|
||||
case SEC_OID_SHA1:
|
||||
return SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
|
||||
default:
|
||||
return SEC_OID_UNKNOWN;
|
||||
}
|
||||
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
|
||||
switch (hashalg) {
|
||||
case SEC_OID_SHA1:
|
||||
return SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
|
||||
default:
|
||||
return SEC_OID_UNKNOWN;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return encalg; /* maybe it is already the right algid */
|
||||
}
|
||||
|
||||
const SEC_ASN1Template *
|
||||
NSS_CMSUtil_GetTemplateByTypeTag(SECOidTag type)
|
||||
{
|
||||
|
|
|
@ -166,6 +166,8 @@
|
|||
#define ANSI_X962_CURVE_OID ANSI_X962_OID, 0x03
|
||||
#define ANSI_X962_GF2m_OID ANSI_X962_CURVE_OID, 0x00
|
||||
#define ANSI_X962_GFp_OID ANSI_X962_CURVE_OID, 0x01
|
||||
#define ANSI_X962_SIGNATURE_OID ANSI_X962_OID, 0x04
|
||||
#define ANSI_X962_SPECIFY_OID ANSI_X962_SIGNATURE_OID, 0x03
|
||||
|
||||
#define CONST_OID static const unsigned char
|
||||
|
||||
|
@ -453,8 +455,14 @@ CONST_OID sha256[] = { SHAXXX, 1 };
|
|||
CONST_OID sha384[] = { SHAXXX, 2 };
|
||||
CONST_OID sha512[] = { SHAXXX, 3 };
|
||||
|
||||
CONST_OID ansix962ECPublicKey[] = { ANSI_X962_OID, 0x02, 0x01 };
|
||||
CONST_OID ansix962ECDSASignaturewithSHA1Digest[] = { ANSI_X962_OID, 0x04, 0x01 };
|
||||
CONST_OID ansix962ECPublicKey[] = { ANSI_X962_OID, 0x02, 0x01 };
|
||||
CONST_OID ansix962SignaturewithSHA1Digest[] = { ANSI_X962_SIGNATURE_OID, 0x01 };
|
||||
CONST_OID ansix962SignatureRecommended[] = { ANSI_X962_SIGNATURE_OID, 0x02 };
|
||||
CONST_OID ansix962SignatureSpecified[] = { ANSI_X962_SPECIFY_OID };
|
||||
CONST_OID ansix962SignaturewithSHA224Digest[] = { ANSI_X962_SPECIFY_OID, 0x01 };
|
||||
CONST_OID ansix962SignaturewithSHA256Digest[] = { ANSI_X962_SPECIFY_OID, 0x02 };
|
||||
CONST_OID ansix962SignaturewithSHA384Digest[] = { ANSI_X962_SPECIFY_OID, 0x03 };
|
||||
CONST_OID ansix962SignaturewithSHA512Digest[] = { ANSI_X962_SPECIFY_OID, 0x04 };
|
||||
|
||||
/* ANSI X9.62 prime curve OIDs */
|
||||
/* NOTE: prime192v1 is the same as secp192r1, prime256v1 is the
|
||||
|
@ -1150,8 +1158,8 @@ const static SECOidData oids[] = {
|
|||
OD( ansix962ECPublicKey, SEC_OID_ANSIX962_EC_PUBLIC_KEY,
|
||||
"X9.62 elliptic curve public key", CKM_ECDH1_DERIVE,
|
||||
INVALID_CERT_EXTENSION ),
|
||||
OD( ansix962ECDSASignaturewithSHA1Digest,
|
||||
SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST,
|
||||
OD( ansix962SignaturewithSHA1Digest,
|
||||
SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE,
|
||||
"X9.62 ECDSA signature with SHA1", CKM_ECDSA_SHA1,
|
||||
INVALID_CERT_EXTENSION ),
|
||||
|
||||
|
@ -1435,6 +1443,32 @@ const static SECOidData oids[] = {
|
|||
OD( pkcs9ExtensionRequest, SEC_OID_PKCS9_EXTENSION_REQUEST,
|
||||
"PKCS #9 Extension Request",
|
||||
CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
|
||||
|
||||
/* more ECC Signature Oids */
|
||||
OD( ansix962SignatureRecommended,
|
||||
SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST,
|
||||
"X9.62 ECDSA signature with recommended digest", CKM_INVALID_MECHANISM,
|
||||
INVALID_CERT_EXTENSION ),
|
||||
OD( ansix962SignatureSpecified,
|
||||
SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST,
|
||||
"X9.62 ECDSA signature with specified digest", CKM_ECDSA,
|
||||
INVALID_CERT_EXTENSION ),
|
||||
OD( ansix962SignaturewithSHA224Digest,
|
||||
SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE,
|
||||
"X9.62 ECDSA signature with SHA224", CKM_INVALID_MECHANISM,
|
||||
INVALID_CERT_EXTENSION ),
|
||||
OD( ansix962SignaturewithSHA256Digest,
|
||||
SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE,
|
||||
"X9.62 ECDSA signature with SHA256", CKM_INVALID_MECHANISM,
|
||||
INVALID_CERT_EXTENSION ),
|
||||
OD( ansix962SignaturewithSHA384Digest,
|
||||
SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE,
|
||||
"X9.62 ECDSA signature with SHA384", CKM_INVALID_MECHANISM,
|
||||
INVALID_CERT_EXTENSION ),
|
||||
OD( ansix962SignaturewithSHA512Digest,
|
||||
SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE,
|
||||
"X9.62 ECDSA signature with SHA512", CKM_INVALID_MECHANISM,
|
||||
INVALID_CERT_EXTENSION ),
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
/*
|
||||
* secoidt.h - public data structures for ASN.1 OID functions
|
||||
*
|
||||
* $Id: secoidt.h,v 1.19 2005-03-07 18:34:48 wtchang%redhat.com Exp $
|
||||
* $Id: secoidt.h,v 1.20 2006-02-08 06:14:31 rrelyea%redhat.com Exp $
|
||||
*/
|
||||
|
||||
#include "secitem.h"
|
||||
|
@ -314,7 +314,10 @@ typedef enum {
|
|||
|
||||
/* Elliptic Curve Cryptography (ECC) OIDs */
|
||||
SEC_OID_ANSIX962_EC_PUBLIC_KEY = 200,
|
||||
SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST = 201,
|
||||
SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE = 201,
|
||||
|
||||
#define SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST \
|
||||
SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE
|
||||
|
||||
/* ANSI X9.62 named elliptic curves (prime field) */
|
||||
SEC_OID_ANSIX962_EC_PRIME192V1 = 202,
|
||||
|
@ -403,6 +406,13 @@ typedef enum {
|
|||
SEC_OID_PKIX_CA_ISSUERS = 273,
|
||||
SEC_OID_PKCS9_EXTENSION_REQUEST = 274,
|
||||
|
||||
/* new EC Signature oids */
|
||||
SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST = 275,
|
||||
SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST = 276,
|
||||
SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE = 277,
|
||||
SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE = 278,
|
||||
SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE = 279,
|
||||
SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE = 280,
|
||||
SEC_OID_TOTAL
|
||||
} SECOidTag;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче