зеркало из https://github.com/mozilla/pjs.git
bug 125359, by default the ASN.1 en/decoder should treat all numbers as signed. But many source/target items desire unsigned integers (specifically, bignums in the crypto stuff), so implement an siUnsignedInteger type which notifies the en/decoder to handle the conversion.
r=nelsonb
This commit is contained in:
Родитель
6cabe1f1a6
Коммит
e5c7125aba
|
@ -149,8 +149,10 @@ DSAU_EncodeDerSig(SECItem *dest, SECItem *src)
|
||||||
** prepend with leading zero.
|
** prepend with leading zero.
|
||||||
** Must remove all but one leading zero byte from numbers.
|
** Must remove all but one leading zero byte from numbers.
|
||||||
*/
|
*/
|
||||||
|
sig.r.type = siUnsignedInteger;
|
||||||
sig.r.data = signedR;
|
sig.r.data = signedR;
|
||||||
sig.r.len = sizeof signedR;
|
sig.r.len = sizeof signedR;
|
||||||
|
sig.s.type = siUnsignedInteger;
|
||||||
sig.s.data = signedS;
|
sig.s.data = signedS;
|
||||||
sig.s.len = sizeof signedR;
|
sig.s.len = sizeof signedR;
|
||||||
|
|
||||||
|
@ -193,6 +195,8 @@ DSAU_DecodeDerSig(SECItem *item)
|
||||||
if (result->data == NULL)
|
if (result->data == NULL)
|
||||||
goto loser;
|
goto loser;
|
||||||
|
|
||||||
|
sig.r.type = siUnsignedInteger;
|
||||||
|
sig.s.type = siUnsignedInteger;
|
||||||
status = SEC_ASN1DecodeItem(NULL, &sig, DSA_SignatureTemplate, item);
|
status = SEC_ASN1DecodeItem(NULL, &sig, DSA_SignatureTemplate, item);
|
||||||
if (status != SECSuccess)
|
if (status != SECSuccess)
|
||||||
goto loser;
|
goto loser;
|
||||||
|
|
|
@ -143,6 +143,48 @@ SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_DSAPublicKeyTemplate)
|
||||||
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_RSAPublicKeyTemplate)
|
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_RSAPublicKeyTemplate)
|
||||||
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SubjectPublicKeyInfoTemplate)
|
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SubjectPublicKeyInfoTemplate)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See bugzilla bug 125359
|
||||||
|
* Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
|
||||||
|
* all of the templates above that en/decode into integers must be converted
|
||||||
|
* from ASN.1's signed integer type. This is done by marking either the
|
||||||
|
* source or destination (encoding or decoding, respectively) type as
|
||||||
|
* siUnsignedInteger.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
prepare_rsa_pub_key_for_asn1(SECKEYPublicKey *pubk)
|
||||||
|
{
|
||||||
|
pubk->u.rsa.modulus.type = siUnsignedInteger;
|
||||||
|
pubk->u.rsa.publicExponent.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_dsa_pub_key_for_asn1(SECKEYPublicKey *pubk)
|
||||||
|
{
|
||||||
|
pubk->u.dsa.publicValue.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_pqg_params_for_asn1(SECKEYPQGParams *params)
|
||||||
|
{
|
||||||
|
params->prime.type = siUnsignedInteger;
|
||||||
|
params->subPrime.type = siUnsignedInteger;
|
||||||
|
params->base.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_dh_pub_key_for_asn1(SECKEYPublicKey *pubk)
|
||||||
|
{
|
||||||
|
pubk->u.dh.prime.type = siUnsignedInteger;
|
||||||
|
pubk->u.dh.base.type = siUnsignedInteger;
|
||||||
|
pubk->u.dh.publicValue.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_kea_pub_key_for_asn1(SECKEYPublicKey *pubk)
|
||||||
|
{
|
||||||
|
pubk->u.kea.publicValue.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create an RSA key pair is any slot able to do so.
|
/* Create an RSA key pair is any slot able to do so.
|
||||||
** The created keys are "session" (temporary), not "token" (permanent),
|
** The created keys are "session" (temporary), not "token" (permanent),
|
||||||
|
@ -509,6 +551,7 @@ SECKEY_FortezzaDecodePQGtoOld(PRArenaPool *arena, SECKEYPublicKey *pubk,
|
||||||
/* PQG params are in the standard format */
|
/* PQG params are in the standard format */
|
||||||
|
|
||||||
/* Store DSA PQG parameters */
|
/* Store DSA PQG parameters */
|
||||||
|
prepare_pqg_params_for_asn1(&pubk->u.fortezza.params);
|
||||||
rv = SEC_ASN1DecodeItem(arena, &pubk->u.fortezza.params,
|
rv = SEC_ASN1DecodeItem(arena, &pubk->u.fortezza.params,
|
||||||
SECKEY_PQGParamsTemplate,
|
SECKEY_PQGParamsTemplate,
|
||||||
params);
|
params);
|
||||||
|
@ -628,6 +671,7 @@ SECKEY_DSADecodePQG(PRArenaPool *arena, SECKEYPublicKey *pubk, SECItem *params)
|
||||||
(params->data[0] != 0xa0)) {
|
(params->data[0] != 0xa0)) {
|
||||||
|
|
||||||
/* PQG params are in the standard format */
|
/* PQG params are in the standard format */
|
||||||
|
prepare_pqg_params_for_asn1(&pubk->u.dsa.params);
|
||||||
rv = SEC_ASN1DecodeItem(arena, &pubk->u.dsa.params,
|
rv = SEC_ASN1DecodeItem(arena, &pubk->u.dsa.params,
|
||||||
SECKEY_PQGParamsTemplate,
|
SECKEY_PQGParamsTemplate,
|
||||||
params);
|
params);
|
||||||
|
@ -875,6 +919,7 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
|
||||||
case SEC_OID_X500_RSA_ENCRYPTION:
|
case SEC_OID_X500_RSA_ENCRYPTION:
|
||||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||||
pubk->keyType = rsaKey;
|
pubk->keyType = rsaKey;
|
||||||
|
prepare_rsa_pub_key_for_asn1(pubk);
|
||||||
rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, &os);
|
rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, &os);
|
||||||
if (rv == SECSuccess)
|
if (rv == SECSuccess)
|
||||||
return pubk;
|
return pubk;
|
||||||
|
@ -882,6 +927,7 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
|
||||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||||
case SEC_OID_SDN702_DSA_SIGNATURE:
|
case SEC_OID_SDN702_DSA_SIGNATURE:
|
||||||
pubk->keyType = dsaKey;
|
pubk->keyType = dsaKey;
|
||||||
|
prepare_dsa_pub_key_for_asn1(pubk);
|
||||||
rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_DSAPublicKeyTemplate, &os);
|
rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_DSAPublicKeyTemplate, &os);
|
||||||
if (rv != SECSuccess) break;
|
if (rv != SECSuccess) break;
|
||||||
|
|
||||||
|
@ -892,6 +938,7 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
|
||||||
break;
|
break;
|
||||||
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
|
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
|
||||||
pubk->keyType = dhKey;
|
pubk->keyType = dhKey;
|
||||||
|
prepare_dh_pub_key_for_asn1(pubk);
|
||||||
rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_DHPublicKeyTemplate, &os);
|
rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_DHPublicKeyTemplate, &os);
|
||||||
if (rv != SECSuccess) break;
|
if (rv != SECSuccess) break;
|
||||||
|
|
||||||
|
@ -914,6 +961,7 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
|
||||||
case SEC_OID_MISSI_KEA:
|
case SEC_OID_MISSI_KEA:
|
||||||
pubk->keyType = keaKey;
|
pubk->keyType = keaKey;
|
||||||
|
|
||||||
|
prepare_kea_pub_key_for_asn1(pubk);
|
||||||
rv = SEC_ASN1DecodeItem(arena, pubk,
|
rv = SEC_ASN1DecodeItem(arena, pubk,
|
||||||
SECKEY_KEAPublicKeyTemplate, &os);
|
SECKEY_KEAPublicKeyTemplate, &os);
|
||||||
if (rv != SECSuccess) break;
|
if (rv != SECSuccess) break;
|
||||||
|
@ -1269,6 +1317,7 @@ SECKEY_CreateSubjectPublicKeyInfo(SECKEYPublicKey *pubk)
|
||||||
/*
|
/*
|
||||||
* DER encode the public key into the subjectPublicKeyInfo.
|
* DER encode the public key into the subjectPublicKeyInfo.
|
||||||
*/
|
*/
|
||||||
|
prepare_rsa_pub_key_for_asn1(pubk);
|
||||||
rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,
|
rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,
|
||||||
pubk, SECKEY_RSAPublicKeyTemplate);
|
pubk, SECKEY_RSAPublicKeyTemplate);
|
||||||
if (rv_item != NULL) {
|
if (rv_item != NULL) {
|
||||||
|
@ -1286,6 +1335,7 @@ SECKEY_CreateSubjectPublicKeyInfo(SECKEYPublicKey *pubk)
|
||||||
break;
|
break;
|
||||||
case dsaKey:
|
case dsaKey:
|
||||||
/* DER encode the params. */
|
/* DER encode the params. */
|
||||||
|
prepare_pqg_params_for_asn1(&pubk->u.dsa.params);
|
||||||
rv_item = SEC_ASN1EncodeItem(arena, ¶ms, &pubk->u.dsa.params,
|
rv_item = SEC_ASN1EncodeItem(arena, ¶ms, &pubk->u.dsa.params,
|
||||||
SECKEY_PQGParamsTemplate);
|
SECKEY_PQGParamsTemplate);
|
||||||
if (rv_item != NULL) {
|
if (rv_item != NULL) {
|
||||||
|
@ -1296,6 +1346,7 @@ SECKEY_CreateSubjectPublicKeyInfo(SECKEYPublicKey *pubk)
|
||||||
/*
|
/*
|
||||||
* DER encode the public key into the subjectPublicKeyInfo.
|
* DER encode the public key into the subjectPublicKeyInfo.
|
||||||
*/
|
*/
|
||||||
|
prepare_dsa_pub_key_for_asn1(pubk);
|
||||||
rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,
|
rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,
|
||||||
pubk,
|
pubk,
|
||||||
SECKEY_DSAPublicKeyTemplate);
|
SECKEY_DSAPublicKeyTemplate);
|
||||||
|
@ -1390,6 +1441,7 @@ SECKEY_DecodeDERPublicKey(SECItem *pubkder)
|
||||||
pubk->arena = arena;
|
pubk->arena = arena;
|
||||||
pubk->pkcs11Slot = NULL;
|
pubk->pkcs11Slot = NULL;
|
||||||
pubk->pkcs11ID = 0;
|
pubk->pkcs11ID = 0;
|
||||||
|
prepare_rsa_pub_key_for_asn1(pubk);
|
||||||
rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate,
|
rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate,
|
||||||
pubkder);
|
pubkder);
|
||||||
if (rv == SECSuccess)
|
if (rv == SECSuccess)
|
||||||
|
@ -1732,14 +1784,17 @@ SECKEY_ImportDERPublicKey(SECItem *derKey, CK_KEY_TYPE type)
|
||||||
|
|
||||||
switch( type ) {
|
switch( type ) {
|
||||||
case CKK_RSA:
|
case CKK_RSA:
|
||||||
|
prepare_rsa_pub_key_for_asn1(pubk);
|
||||||
rv = SEC_ASN1DecodeItem(NULL, pubk, SECKEY_RSAPublicKeyTemplate,derKey);
|
rv = SEC_ASN1DecodeItem(NULL, pubk, SECKEY_RSAPublicKeyTemplate,derKey);
|
||||||
pubk->keyType = rsaKey;
|
pubk->keyType = rsaKey;
|
||||||
break;
|
break;
|
||||||
case CKK_DSA:
|
case CKK_DSA:
|
||||||
|
prepare_dsa_pub_key_for_asn1(pubk);
|
||||||
rv = SEC_ASN1DecodeItem(NULL, pubk, SECKEY_DSAPublicKeyTemplate,derKey);
|
rv = SEC_ASN1DecodeItem(NULL, pubk, SECKEY_DSAPublicKeyTemplate,derKey);
|
||||||
pubk->keyType = dsaKey;
|
pubk->keyType = dsaKey;
|
||||||
break;
|
break;
|
||||||
case CKK_DH:
|
case CKK_DH:
|
||||||
|
prepare_dh_pub_key_for_asn1(pubk);
|
||||||
rv = SEC_ASN1DecodeItem(NULL, pubk, SECKEY_DHPublicKeyTemplate, derKey);
|
rv = SEC_ASN1DecodeItem(NULL, pubk, SECKEY_DHPublicKeyTemplate, derKey);
|
||||||
pubk->keyType = dhKey;
|
pubk->keyType = dhKey;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -185,6 +185,45 @@ SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate)
|
||||||
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate)
|
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate)
|
||||||
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate)
|
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See bugzilla bug 125359
|
||||||
|
* Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
|
||||||
|
* all of the templates above that en/decode into integers must be converted
|
||||||
|
* from ASN.1's signed integer type. This is done by marking either the
|
||||||
|
* source or destination (encoding or decoding, respectively) type as
|
||||||
|
* siUnsignedInteger.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_rsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
|
||||||
|
{
|
||||||
|
key->u.rsa.modulus.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.publicExponent.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.privateExponent.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.prime1.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.prime2.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.exponent1.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.exponent2.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.coefficient.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_dsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
|
||||||
|
{
|
||||||
|
key->u.dsa.privateValue.type = siUnsignedInteger;
|
||||||
|
key->u.dsa.params.prime.type = siUnsignedInteger;
|
||||||
|
key->u.dsa.params.subPrime.type = siUnsignedInteger;
|
||||||
|
key->u.dsa.params.base.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
|
||||||
|
{
|
||||||
|
key->u.dh.privateValue.type = siUnsignedInteger;
|
||||||
|
key->u.dh.prime.type = siUnsignedInteger;
|
||||||
|
key->u.dh.base.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI,
|
PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI,
|
||||||
|
@ -437,6 +476,7 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
|
||||||
|
|
||||||
switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
|
switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
|
||||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||||
|
prepare_rsa_priv_key_export_for_asn1(lpk);
|
||||||
keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;
|
keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;
|
||||||
paramTemplate = NULL;
|
paramTemplate = NULL;
|
||||||
paramDest = NULL;
|
paramDest = NULL;
|
||||||
|
@ -444,6 +484,7 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
|
||||||
keyType = CKK_RSA;
|
keyType = CKK_RSA;
|
||||||
break;
|
break;
|
||||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||||
|
prepare_dsa_priv_key_export_for_asn1(lpk);
|
||||||
keyTemplate = SECKEY_DSAPrivateKeyExportTemplate;
|
keyTemplate = SECKEY_DSAPrivateKeyExportTemplate;
|
||||||
paramTemplate = SECKEY_PQGParamsTemplate;
|
paramTemplate = SECKEY_PQGParamsTemplate;
|
||||||
paramDest = &(lpk->u.dsa.params);
|
paramDest = &(lpk->u.dsa.params);
|
||||||
|
@ -454,6 +495,7 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
|
||||||
if(!publicValue) {
|
if(!publicValue) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
prepare_dh_priv_key_export_for_asn1(lpk);
|
||||||
keyTemplate = SECKEY_DHPrivateKeyExportTemplate;
|
keyTemplate = SECKEY_DHPrivateKeyExportTemplate;
|
||||||
paramTemplate = NULL;
|
paramTemplate = NULL;
|
||||||
paramDest = NULL;
|
paramDest = NULL;
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*
|
*
|
||||||
* Private Key Database code
|
* Private Key Database code
|
||||||
*
|
*
|
||||||
* $Id: keydb.c,v 1.12 2001-12-07 01:36:17 relyea%netscape.com Exp $
|
* $Id: keydb.c,v 1.13 2002-02-21 22:41:37 ian.mcgreer%sun.com Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lowkeyi.h"
|
#include "lowkeyi.h"
|
||||||
|
@ -1579,6 +1579,7 @@ seckey_encrypt_private_key(
|
||||||
/* Encode the key, and set the algorithm (with params) */
|
/* Encode the key, and set the algorithm (with params) */
|
||||||
switch (pk->keyType) {
|
switch (pk->keyType) {
|
||||||
case NSSLOWKEYRSAKey:
|
case NSSLOWKEYRSAKey:
|
||||||
|
prepare_low_rsa_priv_key_for_asn1(pk);
|
||||||
dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
|
dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
|
||||||
nsslowkey_RSAPrivateKeyTemplate);
|
nsslowkey_RSAPrivateKeyTemplate);
|
||||||
if (dummy == NULL) {
|
if (dummy == NULL) {
|
||||||
|
@ -1594,6 +1595,7 @@ seckey_encrypt_private_key(
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case NSSLOWKEYDSAKey:
|
case NSSLOWKEYDSAKey:
|
||||||
|
prepare_low_dsa_priv_key_for_asn1(pk);
|
||||||
dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
|
dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
|
||||||
nsslowkey_DSAPrivateKeyTemplate);
|
nsslowkey_DSAPrivateKeyTemplate);
|
||||||
if (dummy == NULL) {
|
if (dummy == NULL) {
|
||||||
|
@ -1601,6 +1603,7 @@ seckey_encrypt_private_key(
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepare_low_pqg_params_for_asn1(&pk->u.dsa.params);
|
||||||
dummy = SEC_ASN1EncodeItem(temparena, NULL, &pk->u.dsa.params,
|
dummy = SEC_ASN1EncodeItem(temparena, NULL, &pk->u.dsa.params,
|
||||||
nsslowkey_PQGParamsTemplate);
|
nsslowkey_PQGParamsTemplate);
|
||||||
if (dummy == NULL) {
|
if (dummy == NULL) {
|
||||||
|
@ -1616,6 +1619,7 @@ seckey_encrypt_private_key(
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case NSSLOWKEYDHKey:
|
case NSSLOWKEYDHKey:
|
||||||
|
prepare_low_dh_priv_key_for_asn1(pk);
|
||||||
dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
|
dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
|
||||||
nsslowkey_DHPrivateKeyTemplate);
|
nsslowkey_DHPrivateKeyTemplate);
|
||||||
if (dummy == NULL) {
|
if (dummy == NULL) {
|
||||||
|
@ -1860,23 +1864,27 @@ seckey_decrypt_private_key(NSSLOWKEYEncryptedPrivateKeyInfo *epki,
|
||||||
case SEC_OID_X500_RSA_ENCRYPTION:
|
case SEC_OID_X500_RSA_ENCRYPTION:
|
||||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||||
pk->keyType = NSSLOWKEYRSAKey;
|
pk->keyType = NSSLOWKEYRSAKey;
|
||||||
|
prepare_low_rsa_priv_key_for_asn1(pk);
|
||||||
rv = SEC_ASN1DecodeItem(permarena, pk,
|
rv = SEC_ASN1DecodeItem(permarena, pk,
|
||||||
nsslowkey_RSAPrivateKeyTemplate,
|
nsslowkey_RSAPrivateKeyTemplate,
|
||||||
&pki->privateKey);
|
&pki->privateKey);
|
||||||
break;
|
break;
|
||||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||||
pk->keyType = NSSLOWKEYDSAKey;
|
pk->keyType = NSSLOWKEYDSAKey;
|
||||||
|
prepare_low_dsa_priv_key_for_asn1(pk);
|
||||||
rv = SEC_ASN1DecodeItem(permarena, pk,
|
rv = SEC_ASN1DecodeItem(permarena, pk,
|
||||||
nsslowkey_DSAPrivateKeyTemplate,
|
nsslowkey_DSAPrivateKeyTemplate,
|
||||||
&pki->privateKey);
|
&pki->privateKey);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
goto loser;
|
goto loser;
|
||||||
|
prepare_low_pqg_params_for_asn1(&pk->u.dsa.params);
|
||||||
rv = SEC_ASN1DecodeItem(permarena, &pk->u.dsa.params,
|
rv = SEC_ASN1DecodeItem(permarena, &pk->u.dsa.params,
|
||||||
nsslowkey_PQGParamsTemplate,
|
nsslowkey_PQGParamsTemplate,
|
||||||
&pki->algorithm.parameters);
|
&pki->algorithm.parameters);
|
||||||
break;
|
break;
|
||||||
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
|
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
|
||||||
pk->keyType = NSSLOWKEYDHKey;
|
pk->keyType = NSSLOWKEYDHKey;
|
||||||
|
prepare_low_dh_priv_key_for_asn1(pk);
|
||||||
rv = SEC_ASN1DecodeItem(permarena, pk,
|
rv = SEC_ASN1DecodeItem(permarena, pk,
|
||||||
nsslowkey_DHPrivateKeyTemplate,
|
nsslowkey_DHPrivateKeyTemplate,
|
||||||
&pki->privateKey);
|
&pki->privateKey);
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
/*
|
/*
|
||||||
* Certificate handling code
|
* Certificate handling code
|
||||||
*
|
*
|
||||||
* $Id: lowcert.c,v 1.5 2002-01-17 00:20:52 ian.mcgreer%sun.com Exp $
|
* $Id: lowcert.c,v 1.6 2002-02-21 22:41:37 ian.mcgreer%sun.com Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "seccomon.h"
|
#include "seccomon.h"
|
||||||
|
@ -117,6 +117,39 @@ const SEC_ASN1Template nsslowcert_DHPublicKeyTemplate[] = {
|
||||||
{ 0, }
|
{ 0, }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See bugzilla bug 125359
|
||||||
|
* Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
|
||||||
|
* all of the templates above that en/decode into integers must be converted
|
||||||
|
* from ASN.1's signed integer type. This is done by marking either the
|
||||||
|
* source or destination (encoding or decoding, respectively) type as
|
||||||
|
* siUnsignedInteger.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_low_rsa_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
|
||||||
|
{
|
||||||
|
pubk->u.rsa.modulus.type = siUnsignedInteger;
|
||||||
|
pubk->u.rsa.publicExponent.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_low_dsa_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
|
||||||
|
{
|
||||||
|
pubk->u.dsa.publicValue.type = siUnsignedInteger;
|
||||||
|
pubk->u.dsa.params.prime.type = siUnsignedInteger;
|
||||||
|
pubk->u.dsa.params.subPrime.type = siUnsignedInteger;
|
||||||
|
pubk->u.dsa.params.base.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_low_dh_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
|
||||||
|
{
|
||||||
|
pubk->u.dh.prime.type = siUnsignedInteger;
|
||||||
|
pubk->u.dh.base.type = siUnsignedInteger;
|
||||||
|
pubk->u.dh.publicValue.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allow use of default cert database, so that apps(such as mozilla) don't
|
* Allow use of default cert database, so that apps(such as mozilla) don't
|
||||||
* have to pass the handle all over the place.
|
* have to pass the handle all over the place.
|
||||||
|
@ -339,45 +372,23 @@ nsslowcert_FixupEmailAddr(char *emailAddr)
|
||||||
return(retaddr);
|
return(retaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NSS has traditionally keyed certificate entries in the cert database
|
|
||||||
* by (serial number, DER_ISSUER). The serial number may have a leading zero
|
|
||||||
* in order to make it a signed integer. However, the ASN.1 decoder now
|
|
||||||
* strips the leading zero, treating any INTEGER as unsigned. In order to
|
|
||||||
* be compatible with version 7 of the database, it is necessary to reapply
|
|
||||||
* that leading zero to the serial number when needed, before computing the
|
|
||||||
* database key.
|
|
||||||
*/
|
|
||||||
static SECStatus
|
static SECStatus
|
||||||
nsslowcert_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, SECItem *sn,
|
nsslowcert_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, SECItem *sn,
|
||||||
SECItem *key)
|
SECItem *key)
|
||||||
{
|
{
|
||||||
PRBool leadingZero = PR_FALSE;
|
|
||||||
int start;
|
|
||||||
|
|
||||||
key->len = sn->len + issuer->len;
|
key->len = sn->len + issuer->len;
|
||||||
|
|
||||||
if (sn->data[0] & 0x80) {
|
|
||||||
leadingZero = PR_TRUE;
|
|
||||||
key->len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
key->data = (unsigned char*)PORT_ArenaAlloc(arena, key->len);
|
key->data = (unsigned char*)PORT_ArenaAlloc(arena, key->len);
|
||||||
if ( !key->data ) {
|
if ( !key->data ) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (leadingZero) {
|
|
||||||
key->data[0] = 0;
|
|
||||||
start = 1;
|
|
||||||
} else {
|
|
||||||
start = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy the serialNumber */
|
/* copy the serialNumber */
|
||||||
PORT_Memcpy(key->data + start, sn->data, sn->len);
|
PORT_Memcpy(key->data, sn->data, sn->len);
|
||||||
|
|
||||||
/* copy the issuer */
|
/* copy the issuer */
|
||||||
PORT_Memcpy(&key->data[start + sn->len], issuer->data, issuer->len);
|
PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);
|
||||||
|
|
||||||
return(SECSuccess);
|
return(SECSuccess);
|
||||||
|
|
||||||
|
@ -453,6 +464,7 @@ nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert)
|
||||||
case SEC_OID_X500_RSA_ENCRYPTION:
|
case SEC_OID_X500_RSA_ENCRYPTION:
|
||||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||||
pubk->keyType = NSSLOWKEYRSAKey;
|
pubk->keyType = NSSLOWKEYRSAKey;
|
||||||
|
prepare_low_rsa_pub_key_for_asn1(pubk);
|
||||||
rv = SEC_ASN1DecodeItem(arena, pubk,
|
rv = SEC_ASN1DecodeItem(arena, pubk,
|
||||||
nsslowcert_RSAPublicKeyTemplate, &os);
|
nsslowcert_RSAPublicKeyTemplate, &os);
|
||||||
if (rv == SECSuccess)
|
if (rv == SECSuccess)
|
||||||
|
@ -460,12 +472,14 @@ nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert)
|
||||||
break;
|
break;
|
||||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||||
pubk->keyType = NSSLOWKEYDSAKey;
|
pubk->keyType = NSSLOWKEYDSAKey;
|
||||||
|
prepare_low_dsa_pub_key_for_asn1(pubk);
|
||||||
rv = SEC_ASN1DecodeItem(arena, pubk,
|
rv = SEC_ASN1DecodeItem(arena, pubk,
|
||||||
nsslowcert_DSAPublicKeyTemplate, &os);
|
nsslowcert_DSAPublicKeyTemplate, &os);
|
||||||
if (rv == SECSuccess) return pubk;
|
if (rv == SECSuccess) return pubk;
|
||||||
break;
|
break;
|
||||||
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
|
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
|
||||||
pubk->keyType = NSSLOWKEYDHKey;
|
pubk->keyType = NSSLOWKEYDHKey;
|
||||||
|
prepare_low_dh_pub_key_for_asn1(pubk);
|
||||||
rv = SEC_ASN1DecodeItem(arena, pubk,
|
rv = SEC_ASN1DecodeItem(arena, pubk,
|
||||||
nsslowcert_DHPublicKeyTemplate, &os);
|
nsslowcert_DHPublicKeyTemplate, &os);
|
||||||
if (rv == SECSuccess) return pubk;
|
if (rv == SECSuccess) return pubk;
|
||||||
|
|
|
@ -83,6 +83,61 @@ const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = {
|
||||||
{ 0, }
|
{ 0, }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See bugzilla bug 125359
|
||||||
|
* Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
|
||||||
|
* all of the templates above that en/decode into integers must be converted
|
||||||
|
* from ASN.1's signed integer type. This is done by marking either the
|
||||||
|
* source or destination (encoding or decoding, respectively) type as
|
||||||
|
* siUnsignedInteger.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
|
||||||
|
{
|
||||||
|
key->u.rsa.modulus.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.publicExponent.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.privateExponent.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.prime1.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.prime2.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.exponent1.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.exponent2.type = siUnsignedInteger;
|
||||||
|
key->u.rsa.coefficient.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
prepare_low_pqg_params_for_asn1(PQGParams *params)
|
||||||
|
{
|
||||||
|
params->prime.type = siUnsignedInteger;
|
||||||
|
params->subPrime.type = siUnsignedInteger;
|
||||||
|
params->base.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
|
||||||
|
{
|
||||||
|
key->u.dsa.publicValue.type = siUnsignedInteger;
|
||||||
|
key->u.dsa.privateValue.type = siUnsignedInteger;
|
||||||
|
key->u.dsa.params.prime.type = siUnsignedInteger;
|
||||||
|
key->u.dsa.params.subPrime.type = siUnsignedInteger;
|
||||||
|
key->u.dsa.params.base.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key)
|
||||||
|
{
|
||||||
|
key->u.dsa.privateValue.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
|
||||||
|
{
|
||||||
|
key->u.dh.prime.type = siUnsignedInteger;
|
||||||
|
key->u.dh.base.type = siUnsignedInteger;
|
||||||
|
key->u.dh.publicValue.type = siUnsignedInteger;
|
||||||
|
key->u.dh.privateValue.type = siUnsignedInteger;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk)
|
nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*
|
*
|
||||||
* key.h - public data structures and prototypes for the private key library
|
* key.h - public data structures and prototypes for the private key library
|
||||||
*
|
*
|
||||||
* $Id: lowkeyi.h,v 1.4 2001-12-07 01:36:18 relyea%netscape.com Exp $
|
* $Id: lowkeyi.h,v 1.5 2002-02-21 22:41:38 ian.mcgreer%sun.com Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LOWKEYI_H_
|
#ifndef _LOWKEYI_H_
|
||||||
|
@ -46,6 +46,20 @@
|
||||||
|
|
||||||
SEC_BEGIN_PROTOS
|
SEC_BEGIN_PROTOS
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See bugzilla bug 125359
|
||||||
|
* Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
|
||||||
|
* all of the templates above that en/decode into integers must be converted
|
||||||
|
* from ASN.1's signed integer type. This is done by marking either the
|
||||||
|
* source or destination (encoding or decoding, respectively) type as
|
||||||
|
* siUnsignedInteger.
|
||||||
|
*/
|
||||||
|
extern void prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
|
||||||
|
extern void prepare_low_pqg_params_for_asn1(PQGParams *params);
|
||||||
|
extern void prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
|
||||||
|
extern void prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key);
|
||||||
|
extern void prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
|
||||||
|
|
||||||
typedef char * (* NSSLOWKEYDBNameFunc)(void *arg, int dbVersion);
|
typedef char * (* NSSLOWKEYDBNameFunc)(void *arg, int dbVersion);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -3327,13 +3327,16 @@ static SECItem *pk11_PackagePrivateKey(PK11Object *key)
|
||||||
param = NULL;
|
param = NULL;
|
||||||
switch(lk->keyType) {
|
switch(lk->keyType) {
|
||||||
case NSSLOWKEYRSAKey:
|
case NSSLOWKEYRSAKey:
|
||||||
|
prepare_low_rsa_priv_key_for_asn1(lk);
|
||||||
dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
|
dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
|
||||||
nsslowkey_RSAPrivateKeyTemplate);
|
nsslowkey_RSAPrivateKeyTemplate);
|
||||||
algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
|
algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
|
||||||
break;
|
break;
|
||||||
case NSSLOWKEYDSAKey:
|
case NSSLOWKEYDSAKey:
|
||||||
|
prepare_low_dsa_priv_key_export_for_asn1(lk);
|
||||||
dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
|
dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
|
||||||
nsslowkey_DSAPrivateKeyExportTemplate);
|
nsslowkey_DSAPrivateKeyExportTemplate);
|
||||||
|
prepare_low_pqg_params_for_asn1(&lk->u.dsa.params);
|
||||||
param = SEC_ASN1EncodeItem(NULL, NULL, &(lk->u.dsa.params),
|
param = SEC_ASN1EncodeItem(NULL, NULL, &(lk->u.dsa.params),
|
||||||
nsslowkey_PQGParamsTemplate);
|
nsslowkey_PQGParamsTemplate);
|
||||||
algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE;
|
algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE;
|
||||||
|
@ -3530,12 +3533,15 @@ pk11_unwrapPrivateKey(PK11Object *key, SECItem *bpki)
|
||||||
paramTemplate = NULL;
|
paramTemplate = NULL;
|
||||||
paramDest = NULL;
|
paramDest = NULL;
|
||||||
lpk->keyType = NSSLOWKEYRSAKey;
|
lpk->keyType = NSSLOWKEYRSAKey;
|
||||||
|
prepare_low_rsa_priv_key_for_asn1(lpk);
|
||||||
break;
|
break;
|
||||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||||
keyTemplate = nsslowkey_DSAPrivateKeyExportTemplate;
|
keyTemplate = nsslowkey_DSAPrivateKeyExportTemplate;
|
||||||
paramTemplate = nsslowkey_PQGParamsTemplate;
|
paramTemplate = nsslowkey_PQGParamsTemplate;
|
||||||
paramDest = &(lpk->u.dsa.params);
|
paramDest = &(lpk->u.dsa.params);
|
||||||
lpk->keyType = NSSLOWKEYDSAKey;
|
lpk->keyType = NSSLOWKEYDSAKey;
|
||||||
|
prepare_low_dsa_priv_key_export_for_asn1(lpk);
|
||||||
|
prepare_low_pqg_params_for_asn1(&lpk->u.dsa.params);
|
||||||
break;
|
break;
|
||||||
/* case NSSLOWKEYDHKey: */
|
/* case NSSLOWKEYDHKey: */
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
* Support for DEcoding ASN.1 data based on BER/DER (Basic/Distinguished
|
* Support for DEcoding ASN.1 data based on BER/DER (Basic/Distinguished
|
||||||
* Encoding Rules).
|
* Encoding Rules).
|
||||||
*
|
*
|
||||||
* $Id: secasn1d.c,v 1.14 2002-01-14 23:20:42 ian.mcgreer%sun.com Exp $
|
* $Id: secasn1d.c,v 1.15 2002-02-21 22:41:42 ian.mcgreer%sun.com Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "secasn1.h"
|
#include "secasn1.h"
|
||||||
|
@ -1338,9 +1338,10 @@ sec_asn1d_parse_leaf (sec_asn1d_state *state,
|
||||||
|
|
||||||
item = (SECItem *)(state->dest);
|
item = (SECItem *)(state->dest);
|
||||||
if (item != NULL && item->data != NULL) {
|
if (item != NULL && item->data != NULL) {
|
||||||
/* Strip leading zeroes */
|
/* Strip leading zeroes when target is unsigned integer */
|
||||||
if (state->underlying_kind == SEC_ASN1_INTEGER && /* INTEGER */
|
if (state->underlying_kind == SEC_ASN1_INTEGER && /* INTEGER */
|
||||||
item->len == 0) /* MSB */
|
item->len == 0 && /* MSB */
|
||||||
|
item->type == siUnsignedInteger) /* unsigned */
|
||||||
{
|
{
|
||||||
while (len > 1 && buf[0] == 0) { /* leading 0 */
|
while (len > 1 && buf[0] == 0) { /* leading 0 */
|
||||||
buf++;
|
buf++;
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
* Support for ENcoding ASN.1 data based on BER/DER (Basic/Distinguished
|
* Support for ENcoding ASN.1 data based on BER/DER (Basic/Distinguished
|
||||||
* Encoding Rules).
|
* Encoding Rules).
|
||||||
*
|
*
|
||||||
* $Id: secasn1e.c,v 1.6 2002-01-22 22:48:26 ian.mcgreer%sun.com Exp $
|
* $Id: secasn1e.c,v 1.7 2002-02-21 22:41:42 ian.mcgreer%sun.com Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "secasn1.h"
|
#include "secasn1.h"
|
||||||
|
@ -685,17 +685,18 @@ sec_asn1e_contents_length (const SEC_ASN1Template *theTemplate, void *src,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEC_ASN1_INTEGER:
|
case SEC_ASN1_INTEGER:
|
||||||
/* ASN.1 INTEGERs are signed. PKCS#11 BigIntegers are unsigned. NSS
|
/* ASN.1 INTEGERs are signed.
|
||||||
* will treat numbers going in and out of the ASN.1 encoder as
|
* If the source is an unsigned integer, the encoder will need
|
||||||
* unsigned, so the encoder must handle the conversion.
|
* to handle the conversion here.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned char *buf = ((SECItem *)src)->data;
|
unsigned char *buf = ((SECItem *)src)->data;
|
||||||
|
SECItemType integerType = ((SECItem *)src)->type;
|
||||||
len = ((SECItem *)src)->len;
|
len = ((SECItem *)src)->len;
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
if (*buf != 0) {
|
if (*buf != 0) {
|
||||||
if (*buf & 0x80) {
|
if (*buf & 0x80 && integerType == siUnsignedInteger) {
|
||||||
len++; /* leading zero needed */
|
len++; /* leading zero needed to make number signed */
|
||||||
}
|
}
|
||||||
break; /* reached beginning of number */
|
break; /* reached beginning of number */
|
||||||
}
|
}
|
||||||
|
@ -1007,17 +1008,18 @@ sec_asn1e_write_contents (sec_asn1e_state *state,
|
||||||
goto process_string;
|
goto process_string;
|
||||||
|
|
||||||
case SEC_ASN1_INTEGER:
|
case SEC_ASN1_INTEGER:
|
||||||
/* ASN.1 INTEGERs are signed. PKCS#11 BigIntegers are unsigned.
|
/* ASN.1 INTEGERs are signed. If the source is an unsigned
|
||||||
* NSS will treat numbers going in and out of the ASN.1 encoder as
|
* integer, the encoder will need to handle the conversion here.
|
||||||
* unsigned, so the encoder must handle the conversion.
|
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned int blen;
|
unsigned int blen;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
SECItemType integerType;
|
||||||
blen = ((SECItem *)state->src)->len;
|
blen = ((SECItem *)state->src)->len;
|
||||||
buf = ((SECItem *)state->src)->data;
|
buf = ((SECItem *)state->src)->data;
|
||||||
|
integerType = ((SECItem *)state->src)->type;
|
||||||
while (blen > 0) {
|
while (blen > 0) {
|
||||||
if (*buf & 0x80) {
|
if (*buf & 0x80 && integerType == siUnsignedInteger) {
|
||||||
char zero = 0; /* write a leading 0 */
|
char zero = 0; /* write a leading 0 */
|
||||||
sec_asn1e_write_contents_bytes(state, &zero, 1);
|
sec_asn1e_write_contents_bytes(state, &zero, 1);
|
||||||
/* and then the remaining buffer */
|
/* and then the remaining buffer */
|
||||||
|
@ -1025,10 +1027,16 @@ sec_asn1e_write_contents (sec_asn1e_state *state,
|
||||||
(char *)buf, blen);
|
(char *)buf, blen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*buf != 0 || blen == 1) {
|
/* Check three possibilities:
|
||||||
/* no leading zeros, msb of MSB is not 1, so write
|
* 1. No leading zeros, msb of MSB is not 1;
|
||||||
* the remaining buffer (0 itself also goes here)
|
* 2. The number is zero itself;
|
||||||
*/
|
* 3. Encoding a signed integer with a leading zero,
|
||||||
|
* keep the zero so that the number is positive.
|
||||||
|
*/
|
||||||
|
if (*buf != 0 ||
|
||||||
|
blen == 1 ||
|
||||||
|
(buf[1] & 0x80 && integerType != siUnsignedInteger) )
|
||||||
|
{
|
||||||
sec_asn1e_write_contents_bytes(state,
|
sec_asn1e_write_contents_bytes(state,
|
||||||
(char *)buf, blen);
|
(char *)buf, blen);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
* for security libraries. It should not be dependent on any other
|
* for security libraries. It should not be dependent on any other
|
||||||
* headers, and should not require linking with any libraries.
|
* headers, and should not require linking with any libraries.
|
||||||
*
|
*
|
||||||
* $Id: seccomon.h,v 1.2 2001-01-18 16:36:43 wtc%netscape.com Exp $
|
* $Id: seccomon.h,v 1.3 2002-02-21 22:41:44 ian.mcgreer%sun.com Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SECCOMMON_H_
|
#ifndef _SECCOMMON_H_
|
||||||
|
@ -67,7 +67,8 @@ typedef enum {
|
||||||
siEncodedNameBuffer = 6,
|
siEncodedNameBuffer = 6,
|
||||||
siAsciiNameString = 7,
|
siAsciiNameString = 7,
|
||||||
siAsciiString = 8,
|
siAsciiString = 8,
|
||||||
siDEROID = 9
|
siDEROID = 9,
|
||||||
|
siUnsignedInteger = 10
|
||||||
} SECItemType;
|
} SECItemType;
|
||||||
|
|
||||||
typedef struct SECItemStr SECItem;
|
typedef struct SECItemStr SECItem;
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
/*
|
/*
|
||||||
* Support routines for SECItem data structure.
|
* Support routines for SECItem data structure.
|
||||||
*
|
*
|
||||||
* $Id: secitem.c,v 1.5 2001-12-07 01:36:25 relyea%netscape.com Exp $
|
* $Id: secitem.c,v 1.6 2002-02-21 22:41:44 ian.mcgreer%sun.com Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "seccomon.h"
|
#include "seccomon.h"
|
||||||
|
@ -196,6 +196,7 @@ SECITEM_DupItem(const SECItem *from)
|
||||||
SECStatus
|
SECStatus
|
||||||
SECITEM_CopyItem(PRArenaPool *arena, SECItem *to, const SECItem *from)
|
SECITEM_CopyItem(PRArenaPool *arena, SECItem *to, const SECItem *from)
|
||||||
{
|
{
|
||||||
|
to->type = from->type;
|
||||||
if (from->data && from->len) {
|
if (from->data && from->len) {
|
||||||
if ( arena ) {
|
if ( arena ) {
|
||||||
to->data = (unsigned char*) PORT_ArenaAlloc(arena, from->len);
|
to->data = (unsigned char*) PORT_ArenaAlloc(arena, from->len);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче