Mercurial > trustbridge > nss-cmake-static
diff nss/lib/softoken/lowkey.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nss/lib/softoken/lowkey.c Mon Jul 28 10:47:06 2014 +0200 @@ -0,0 +1,492 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "lowkeyi.h" +#include "secoid.h" +#include "secitem.h" +#include "secder.h" +#include "base64.h" +#include "secasn1.h" +#include "secerr.h" + +#ifndef NSS_DISABLE_ECC +#include "softoken.h" +#endif + +SEC_ASN1_MKSUB(SEC_AnyTemplate) +SEC_ASN1_MKSUB(SEC_BitStringTemplate) +SEC_ASN1_MKSUB(SEC_ObjectIDTemplate) +SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) + +const SEC_ASN1Template nsslowkey_AttributeTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSSLOWKEYAttribute) }, + { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) }, + { SEC_ASN1_SET_OF | SEC_ASN1_XTRN , + offsetof(NSSLOWKEYAttribute, attrValue), + SEC_ASN1_SUB(SEC_AnyTemplate) }, + { 0 } +}; + +const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = { + { SEC_ASN1_SET_OF, 0, nsslowkey_AttributeTemplate }, +}; +/* ASN1 Templates for new decoder/encoder */ +const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) }, + { SEC_ASN1_INTEGER, + offsetof(NSSLOWKEYPrivateKeyInfo,version) }, + { SEC_ASN1_INLINE | SEC_ASN1_XTRN, + offsetof(NSSLOWKEYPrivateKeyInfo,algorithm), + SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, + { SEC_ASN1_OCTET_STRING, + offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, + offsetof(NSSLOWKEYPrivateKeyInfo, attributes), + nsslowkey_SetOfAttributeTemplate }, + { 0 } +}; + +const SEC_ASN1Template nsslowkey_PQGParamsTemplate[] = { + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) }, + { SEC_ASN1_INTEGER, offsetof(PQGParams,prime) }, + { SEC_ASN1_INTEGER, offsetof(PQGParams,subPrime) }, + { SEC_ASN1_INTEGER, offsetof(PQGParams,base) }, + { 0, } +}; + +const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[] = { + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.version) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.modulus) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.publicExponent) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.privateExponent) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime1) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime2) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent1) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent2) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.coefficient) }, + { 0 } +}; + + +const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[] = { + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.publicValue) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) }, + { 0, } +}; + +const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[] = { + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) }, +}; + +const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = { + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.publicValue) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.privateValue) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.base) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.prime) }, + { 0, } +}; + +#ifndef NSS_DISABLE_ECC + +/* XXX This is just a placeholder for later when we support + * generic curves and need full-blown support for parsing EC + * parameters. For now, we only support named curves in which + * EC params are simply encoded as an object ID and we don't + * use nsslowkey_ECParamsTemplate. + */ +const SEC_ASN1Template nsslowkey_ECParamsTemplate[] = { + { SEC_ASN1_CHOICE, offsetof(ECParams,type), NULL, sizeof(ECParams) }, + { SEC_ASN1_OBJECT_ID, offsetof(ECParams,curveOID), NULL, ec_params_named }, + { 0, } +}; + + +/* NOTE: The SECG specification allows the private key structure + * to contain curve parameters but recommends that they be stored + * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo + * instead. + */ +const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[] = { + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, + { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.ec.version) }, + { SEC_ASN1_OCTET_STRING, + offsetof(NSSLOWKEYPrivateKey,u.ec.privateValue) }, + /* XXX The following template works for now since we only + * support named curves for which the parameters are + * encoded as an object ID. When we support generic curves, + * we'll need to define nsslowkey_ECParamsTemplate + */ +#if 1 + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | + SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_XTRN | 0, + offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams.curveOID), + SEC_ASN1_SUB(SEC_ObjectIDTemplate) }, +#else + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | + SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 0, + offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams), + nsslowkey_ECParamsTemplate }, +#endif + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | + SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_XTRN | 1, + offsetof(NSSLOWKEYPrivateKey,u.ec.publicValue), + SEC_ASN1_SUB(SEC_BitStringTemplate) }, + { 0, } +}; +#endif /* NSS_DISABLE_ECC */ +/* + * 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; +} + +#ifndef NSS_DISABLE_ECC +void +prepare_low_ecparams_for_asn1(ECParams *params) +{ + params->DEREncoding.type = siUnsignedInteger; + params->curveOID.type = siUnsignedInteger; +} + +void +prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) +{ + key->u.ec.version.type = siUnsignedInteger; + key->u.ec.ecParams.DEREncoding.type = siUnsignedInteger; + key->u.ec.ecParams.curveOID.type = siUnsignedInteger; + key->u.ec.privateValue.type = siUnsignedInteger; + key->u.ec.publicValue.type = siUnsignedInteger; +} +#endif /* NSS_DISABLE_ECC */ + +void +nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk) +{ + if (privk && privk->arena) { + PORT_FreeArena(privk->arena, PR_TRUE); + } +} + +void +nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk) +{ + if (pubk && pubk->arena) { + PORT_FreeArena(pubk->arena, PR_FALSE); + } +} +unsigned +nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubk) +{ + unsigned char b0; + + /* interpret modulus length as key strength... in + * fortezza that's the public key length */ + + switch (pubk->keyType) { + case NSSLOWKEYRSAKey: + b0 = pubk->u.rsa.modulus.data[0]; + return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1; + default: + break; + } + return 0; +} + +unsigned +nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privk) +{ + + unsigned char b0; + + switch (privk->keyType) { + case NSSLOWKEYRSAKey: + b0 = privk->u.rsa.modulus.data[0]; + return b0 ? privk->u.rsa.modulus.len : privk->u.rsa.modulus.len - 1; + default: + break; + } + return 0; +} + +NSSLOWKEYPublicKey * +nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) +{ + NSSLOWKEYPublicKey *pubk; + PLArenaPool *arena; + + + arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE); + if (arena == NULL) { + PORT_SetError (SEC_ERROR_NO_MEMORY); + return NULL; + } + + switch(privk->keyType) { + case NSSLOWKEYRSAKey: + case NSSLOWKEYNullKey: + pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, + sizeof (NSSLOWKEYPublicKey)); + if (pubk != NULL) { + SECStatus rv; + + pubk->arena = arena; + pubk->keyType = privk->keyType; + if (privk->keyType == NSSLOWKEYNullKey) return pubk; + rv = SECITEM_CopyItem(arena, &pubk->u.rsa.modulus, + &privk->u.rsa.modulus); + if (rv == SECSuccess) { + rv = SECITEM_CopyItem (arena, &pubk->u.rsa.publicExponent, + &privk->u.rsa.publicExponent); + if (rv == SECSuccess) + return pubk; + } + } else { + PORT_SetError (SEC_ERROR_NO_MEMORY); + } + break; + case NSSLOWKEYDSAKey: + pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, + sizeof(NSSLOWKEYPublicKey)); + if (pubk != NULL) { + SECStatus rv; + + pubk->arena = arena; + pubk->keyType = privk->keyType; + rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue, + &privk->u.dsa.publicValue); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime, + &privk->u.dsa.params.prime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime, + &privk->u.dsa.params.subPrime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base, + &privk->u.dsa.params.base); + if (rv == SECSuccess) return pubk; + } + break; + case NSSLOWKEYDHKey: + pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, + sizeof(NSSLOWKEYPublicKey)); + if (pubk != NULL) { + SECStatus rv; + + pubk->arena = arena; + pubk->keyType = privk->keyType; + rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue, + &privk->u.dh.publicValue); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, &pubk->u.dh.prime, + &privk->u.dh.prime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, &pubk->u.dh.base, + &privk->u.dh.base); + if (rv == SECSuccess) return pubk; + } + break; +#ifndef NSS_DISABLE_ECC + case NSSLOWKEYECKey: + pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, + sizeof(NSSLOWKEYPublicKey)); + if (pubk != NULL) { + SECStatus rv; + + pubk->arena = arena; + pubk->keyType = privk->keyType; + rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, + &privk->u.ec.publicValue); + if (rv != SECSuccess) break; + pubk->u.ec.ecParams.arena = arena; + /* Copy the rest of the params */ + rv = EC_CopyParams(arena, &(pubk->u.ec.ecParams), + &(privk->u.ec.ecParams)); + if (rv == SECSuccess) return pubk; + } + break; +#endif /* NSS_DISABLE_ECC */ + /* No Fortezza in Low Key implementations (Fortezza keys aren't + * stored in our data base */ + default: + break; + } + + PORT_FreeArena (arena, PR_FALSE); + return NULL; +} + +NSSLOWKEYPrivateKey * +nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey) +{ + NSSLOWKEYPrivateKey *returnKey = NULL; + SECStatus rv = SECFailure; + PLArenaPool *poolp; + + if(!privKey) { + return NULL; + } + + poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if(!poolp) { + return NULL; + } + + returnKey = (NSSLOWKEYPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(NSSLOWKEYPrivateKey)); + if(!returnKey) { + rv = SECFailure; + goto loser; + } + + returnKey->keyType = privKey->keyType; + returnKey->arena = poolp; + + switch(privKey->keyType) { + case NSSLOWKEYRSAKey: + rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.modulus), + &(privKey->u.rsa.modulus)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.version), + &(privKey->u.rsa.version)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.publicExponent), + &(privKey->u.rsa.publicExponent)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.privateExponent), + &(privKey->u.rsa.privateExponent)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime1), + &(privKey->u.rsa.prime1)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime2), + &(privKey->u.rsa.prime2)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent1), + &(privKey->u.rsa.exponent1)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent2), + &(privKey->u.rsa.exponent2)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.coefficient), + &(privKey->u.rsa.coefficient)); + if(rv != SECSuccess) break; + break; + case NSSLOWKEYDSAKey: + rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.publicValue), + &(privKey->u.dsa.publicValue)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.privateValue), + &(privKey->u.dsa.privateValue)); + if(rv != SECSuccess) break; + returnKey->u.dsa.params.arena = poolp; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.prime), + &(privKey->u.dsa.params.prime)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.subPrime), + &(privKey->u.dsa.params.subPrime)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.base), + &(privKey->u.dsa.params.base)); + if(rv != SECSuccess) break; + break; + case NSSLOWKEYDHKey: + rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.publicValue), + &(privKey->u.dh.publicValue)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.privateValue), + &(privKey->u.dh.privateValue)); + if(rv != SECSuccess) break; + returnKey->u.dsa.params.arena = poolp; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.prime), + &(privKey->u.dh.prime)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.base), + &(privKey->u.dh.base)); + if(rv != SECSuccess) break; + break; +#ifndef NSS_DISABLE_ECC + case NSSLOWKEYECKey: + rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.version), + &(privKey->u.ec.version)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.publicValue), + &(privKey->u.ec.publicValue)); + if(rv != SECSuccess) break; + rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.privateValue), + &(privKey->u.ec.privateValue)); + if(rv != SECSuccess) break; + returnKey->u.ec.ecParams.arena = poolp; + /* Copy the rest of the params */ + rv = EC_CopyParams(poolp, &(returnKey->u.ec.ecParams), + &(privKey->u.ec.ecParams)); + if (rv != SECSuccess) break; + break; +#endif /* NSS_DISABLE_ECC */ + default: + rv = SECFailure; + } + +loser: + + if(rv != SECSuccess) { + PORT_FreeArena(poolp, PR_TRUE); + returnKey = NULL; + } + + return returnKey; +}