security/nss/lib/softoken/legacydb/lgcreate.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/lib/softoken/legacydb/lgcreate.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,981 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +#include "secitem.h"
     1.8 +#include "pkcs11.h"
     1.9 +#include "lgdb.h" 
    1.10 +#include "pcert.h"
    1.11 +#include "lowkeyi.h"
    1.12 +#include "blapi.h"
    1.13 +#include "secder.h"
    1.14 +#include "secasn1.h"
    1.15 +
    1.16 +#include "keydbi.h" 
    1.17 +
    1.18 +/*
    1.19 + * ******************** Object Creation Utilities ***************************
    1.20 + */
    1.21 +
    1.22 +/*
    1.23 + * check the consistancy and initialize a Certificate Object 
    1.24 + */
    1.25 +static CK_RV
    1.26 +lg_createCertObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
    1.27 +			const CK_ATTRIBUTE *templ, CK_ULONG count)
    1.28 +{
    1.29 +    SECItem derCert;
    1.30 +    NSSLOWCERTCertificate *cert;
    1.31 +    NSSLOWCERTCertTrust *trust = NULL;
    1.32 +    NSSLOWCERTCertTrust userTrust = 
    1.33 +		{ CERTDB_USER, CERTDB_USER, CERTDB_USER };
    1.34 +    NSSLOWCERTCertTrust defTrust = 
    1.35 +		{ CERTDB_TRUSTED_UNKNOWN, 
    1.36 +			CERTDB_TRUSTED_UNKNOWN, CERTDB_TRUSTED_UNKNOWN };
    1.37 +    char *label = NULL;
    1.38 +    char *email = NULL;
    1.39 +    SECStatus rv;
    1.40 +    CK_RV crv;
    1.41 +    PRBool inDB = PR_TRUE;
    1.42 +    NSSLOWCERTCertDBHandle *certHandle = lg_getCertDB(sdb);
    1.43 +    NSSLOWKEYDBHandle *keyHandle = NULL;
    1.44 +    CK_CERTIFICATE_TYPE type;
    1.45 +    const CK_ATTRIBUTE *attribute;
    1.46 +
    1.47 +    /* we can't store any certs private */
    1.48 +    if (lg_isTrue(CKA_PRIVATE, templ, count)) {
    1.49 +	return CKR_ATTRIBUTE_VALUE_INVALID;
    1.50 +    }
    1.51 +	
    1.52 +    /* We only support X.509 Certs for now */
    1.53 +    crv = lg_GetULongAttribute(CKA_CERTIFICATE_TYPE, templ, count, &type);
    1.54 +    if (crv != CKR_OK) {
    1.55 +	return crv;
    1.56 +    }
    1.57 +
    1.58 +    if (type != CKC_X_509) {
    1.59 +	return CKR_ATTRIBUTE_VALUE_INVALID;
    1.60 +    }
    1.61 +
    1.62 +    /* X.509 Certificate */
    1.63 +    
    1.64 +
    1.65 +    if (certHandle == NULL) {
    1.66 +	return CKR_TOKEN_WRITE_PROTECTED;
    1.67 +    }
    1.68 +
    1.69 +    /* get the der cert */ 
    1.70 +    attribute = lg_FindAttribute(CKA_VALUE, templ, count);
    1.71 +    if (!attribute) {
    1.72 +	return CKR_ATTRIBUTE_VALUE_INVALID;
    1.73 +    }
    1.74 +
    1.75 +    derCert.type = 0;
    1.76 +    derCert.data = (unsigned char *)attribute->pValue;
    1.77 +    derCert.len = attribute->ulValueLen ;
    1.78 +
    1.79 +    label = lg_getString(CKA_LABEL, templ, count);
    1.80 +
    1.81 +    cert =  nsslowcert_FindCertByDERCert(certHandle, &derCert);
    1.82 +    if (cert == NULL) {
    1.83 +	cert = nsslowcert_DecodeDERCertificate(&derCert, label);
    1.84 +	inDB = PR_FALSE;
    1.85 +    }
    1.86 +    if (cert == NULL) {
    1.87 +	if (label) PORT_Free(label);
    1.88 +	return CKR_ATTRIBUTE_VALUE_INVALID;
    1.89 +    }
    1.90 +
    1.91 +    keyHandle = lg_getKeyDB(sdb);
    1.92 +    if (keyHandle) {
    1.93 +	if (nsslowkey_KeyForCertExists(keyHandle,cert)) {
    1.94 +	    trust = &userTrust;
    1.95 +	}
    1.96 +    }
    1.97 +
    1.98 +    if (!inDB) {
    1.99 +	if (!trust) trust = &defTrust;
   1.100 +	rv = nsslowcert_AddPermCert(certHandle, cert, label, trust);
   1.101 +    } else {
   1.102 +	rv = trust ? nsslowcert_ChangeCertTrust(certHandle,cert,trust) :
   1.103 +				SECSuccess;
   1.104 +    }
   1.105 +
   1.106 +    if (label) PORT_Free(label);
   1.107 +
   1.108 +    if (rv != SECSuccess) {
   1.109 +	nsslowcert_DestroyCertificate(cert);
   1.110 +	return CKR_DEVICE_ERROR;
   1.111 +    }
   1.112 +
   1.113 +    /*
   1.114 +     * Add a NULL S/MIME profile if necessary.
   1.115 +     */
   1.116 +    email = lg_getString(CKA_NSS_EMAIL, templ, count);
   1.117 +    if (email) {
   1.118 +	certDBEntrySMime *entry;
   1.119 +
   1.120 +	entry = nsslowcert_ReadDBSMimeEntry(certHandle,email);
   1.121 +	if (!entry) {
   1.122 +	    nsslowcert_SaveSMimeProfile(certHandle, email, 
   1.123 +						&cert->derSubject, NULL, NULL);
   1.124 +	} else {
   1.125 +	    nsslowcert_DestroyDBEntry((certDBEntry *)entry);
   1.126 +	}
   1.127 +	PORT_Free(email);
   1.128 +    }
   1.129 +    *handle=lg_mkHandle(sdb,&cert->certKey,LG_TOKEN_TYPE_CERT);
   1.130 +    nsslowcert_DestroyCertificate(cert);
   1.131 +
   1.132 +    return CKR_OK;
   1.133 +}
   1.134 +
   1.135 +unsigned int
   1.136 +lg_MapTrust(CK_TRUST trust, PRBool clientAuth)
   1.137 +{
   1.138 +    unsigned int trustCA = clientAuth ? CERTDB_TRUSTED_CLIENT_CA :
   1.139 +							CERTDB_TRUSTED_CA;
   1.140 +    switch (trust) {
   1.141 +    case CKT_NSS_TRUSTED:
   1.142 +	return CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED;
   1.143 +    case CKT_NSS_TRUSTED_DELEGATOR:
   1.144 +	return CERTDB_VALID_CA|trustCA;
   1.145 +    case CKT_NSS_MUST_VERIFY_TRUST:
   1.146 +	return CERTDB_MUST_VERIFY;
   1.147 +    case CKT_NSS_NOT_TRUSTED:
   1.148 +	return CERTDB_TERMINAL_RECORD;
   1.149 +    case CKT_NSS_VALID_DELEGATOR: /* implies must verify */
   1.150 +	return CERTDB_VALID_CA;
   1.151 +    default:
   1.152 +	break;
   1.153 +    }
   1.154 +    return CERTDB_TRUSTED_UNKNOWN;
   1.155 +}
   1.156 +    
   1.157 +	
   1.158 +/*
   1.159 + * check the consistancy and initialize a Trust Object 
   1.160 + */
   1.161 +static CK_RV
   1.162 +lg_createTrustObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
   1.163 +			const CK_ATTRIBUTE *templ, CK_ULONG count)
   1.164 +{
   1.165 +    const CK_ATTRIBUTE *issuer = NULL;
   1.166 +    const CK_ATTRIBUTE *serial = NULL;
   1.167 +    NSSLOWCERTCertificate *cert = NULL;
   1.168 +    const CK_ATTRIBUTE *trust;
   1.169 +    CK_TRUST sslTrust = CKT_NSS_TRUST_UNKNOWN;
   1.170 +    CK_TRUST clientTrust = CKT_NSS_TRUST_UNKNOWN;
   1.171 +    CK_TRUST emailTrust = CKT_NSS_TRUST_UNKNOWN;
   1.172 +    CK_TRUST signTrust = CKT_NSS_TRUST_UNKNOWN;
   1.173 +    CK_BBOOL stepUp;
   1.174 +    NSSLOWCERTCertTrust dbTrust = { 0 };
   1.175 +    SECStatus rv;
   1.176 +    NSSLOWCERTCertDBHandle *certHandle = lg_getCertDB(sdb);
   1.177 +    NSSLOWCERTIssuerAndSN issuerSN;
   1.178 +
   1.179 +    /* we can't store any certs private */
   1.180 +    if (lg_isTrue(CKA_PRIVATE, templ, count)) {
   1.181 +	return CKR_ATTRIBUTE_VALUE_INVALID;
   1.182 +    }
   1.183 +
   1.184 +    if (certHandle == NULL) {
   1.185 +	return CKR_TOKEN_WRITE_PROTECTED;
   1.186 +    }
   1.187 +
   1.188 +    issuer = lg_FindAttribute(CKA_ISSUER, templ, count);
   1.189 +    serial = lg_FindAttribute(CKA_SERIAL_NUMBER, templ, count);
   1.190 +
   1.191 +    if (issuer && serial) {
   1.192 +	issuerSN.derIssuer.data = (unsigned char *)issuer->pValue;
   1.193 +	issuerSN.derIssuer.len = issuer->ulValueLen ;
   1.194 +
   1.195 +	issuerSN.serialNumber.data = (unsigned char *)serial->pValue;
   1.196 +	issuerSN.serialNumber.len = serial->ulValueLen ;
   1.197 +
   1.198 +	cert = nsslowcert_FindCertByIssuerAndSN(certHandle,&issuerSN);
   1.199 +    }
   1.200 +
   1.201 +    if (cert == NULL) {
   1.202 +	return CKR_ATTRIBUTE_VALUE_INVALID;
   1.203 +    }
   1.204 +	
   1.205 +    lg_GetULongAttribute(CKA_TRUST_SERVER_AUTH, templ, count, &sslTrust);
   1.206 +    lg_GetULongAttribute(CKA_TRUST_CLIENT_AUTH, templ, count, &clientTrust);
   1.207 +    lg_GetULongAttribute(CKA_TRUST_EMAIL_PROTECTION, templ, count, &emailTrust);
   1.208 +    lg_GetULongAttribute(CKA_TRUST_CODE_SIGNING, templ, count, &signTrust);
   1.209 +    stepUp = CK_FALSE;
   1.210 +    trust = lg_FindAttribute(CKA_TRUST_STEP_UP_APPROVED, templ, count);
   1.211 +    if (trust) {
   1.212 +	if (trust->ulValueLen == sizeof(CK_BBOOL)) {
   1.213 +	    stepUp = *(CK_BBOOL*)trust->pValue;
   1.214 +	}
   1.215 +    }
   1.216 +
   1.217 +    /* preserve certain old fields */
   1.218 +    if (cert->trust) {
   1.219 +	dbTrust.sslFlags = cert->trust->sslFlags & CERTDB_PRESERVE_TRUST_BITS;
   1.220 +	dbTrust.emailFlags=
   1.221 +			cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS;
   1.222 +	dbTrust.objectSigningFlags = 
   1.223 +		cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS;
   1.224 +    }
   1.225 +
   1.226 +    dbTrust.sslFlags |= lg_MapTrust(sslTrust,PR_FALSE);
   1.227 +    dbTrust.sslFlags |= lg_MapTrust(clientTrust,PR_TRUE);
   1.228 +    dbTrust.emailFlags |= lg_MapTrust(emailTrust,PR_FALSE);
   1.229 +    dbTrust.objectSigningFlags |= lg_MapTrust(signTrust,PR_FALSE);
   1.230 +    if (stepUp) {
   1.231 +	dbTrust.sslFlags |= CERTDB_GOVT_APPROVED_CA;
   1.232 +    }
   1.233 +
   1.234 +    rv = nsslowcert_ChangeCertTrust(certHandle,cert,&dbTrust);
   1.235 +    *handle=lg_mkHandle(sdb,&cert->certKey,LG_TOKEN_TYPE_TRUST);
   1.236 +    nsslowcert_DestroyCertificate(cert);
   1.237 +    if (rv != SECSuccess) {
   1.238 +	return CKR_DEVICE_ERROR;
   1.239 +    }
   1.240 +
   1.241 +    return CKR_OK;
   1.242 +}
   1.243 +
   1.244 +/*
   1.245 + * check the consistancy and initialize a Trust Object 
   1.246 + */
   1.247 +static CK_RV
   1.248 +lg_createSMimeObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
   1.249 +			const CK_ATTRIBUTE *templ, CK_ULONG count)
   1.250 +{
   1.251 +    SECItem derSubj,rawProfile,rawTime,emailKey;
   1.252 +    SECItem *pRawProfile = NULL;
   1.253 +    SECItem *pRawTime = NULL;
   1.254 +    char *email = NULL;
   1.255 +    const CK_ATTRIBUTE *subject = NULL,
   1.256 +		 *profile = NULL,
   1.257 +		 *time    = NULL;
   1.258 +    SECStatus rv;
   1.259 +    NSSLOWCERTCertDBHandle *certHandle;
   1.260 +    CK_RV ck_rv = CKR_OK;
   1.261 +
   1.262 +    /* we can't store any certs private */
   1.263 +    if (lg_isTrue(CKA_PRIVATE,templ,count)) {
   1.264 +	return CKR_ATTRIBUTE_VALUE_INVALID;
   1.265 +    }
   1.266 +
   1.267 +    certHandle = lg_getCertDB(sdb);
   1.268 +    if (certHandle == NULL) {
   1.269 +	return CKR_TOKEN_WRITE_PROTECTED;
   1.270 +    }
   1.271 +
   1.272 +    /* lookup SUBJECT */
   1.273 +    subject = lg_FindAttribute(CKA_SUBJECT,templ,count);
   1.274 +    PORT_Assert(subject);
   1.275 +    if (!subject) {
   1.276 +	ck_rv = CKR_ATTRIBUTE_VALUE_INVALID;
   1.277 +	goto loser;
   1.278 +    }
   1.279 +
   1.280 +    derSubj.data = (unsigned char *)subject->pValue;
   1.281 +    derSubj.len = subject->ulValueLen ;
   1.282 +    derSubj.type = 0;
   1.283 +
   1.284 +    /* lookup VALUE */
   1.285 +    profile = lg_FindAttribute(CKA_VALUE,templ,count);
   1.286 +    if (profile) {
   1.287 +	rawProfile.data = (unsigned char *)profile->pValue;
   1.288 +	rawProfile.len = profile->ulValueLen ;
   1.289 +	rawProfile.type = siBuffer;
   1.290 +	pRawProfile = &rawProfile;
   1.291 +    }
   1.292 +
   1.293 +    /* lookup Time */
   1.294 +    time = lg_FindAttribute(CKA_NSS_SMIME_TIMESTAMP,templ,count);
   1.295 +    if (time) {
   1.296 +	rawTime.data = (unsigned char *)time->pValue;
   1.297 +	rawTime.len = time->ulValueLen ;
   1.298 +	rawTime.type = siBuffer;
   1.299 +	pRawTime = &rawTime;
   1.300 +    }
   1.301 +
   1.302 +
   1.303 +    email = lg_getString(CKA_NSS_EMAIL,templ,count);
   1.304 +    if (!email) {
   1.305 +	ck_rv = CKR_ATTRIBUTE_VALUE_INVALID;
   1.306 +	goto loser;
   1.307 +    }
   1.308 +
   1.309 +    /* Store S/MIME Profile by SUBJECT */
   1.310 +    rv = nsslowcert_SaveSMimeProfile(certHandle, email, &derSubj, 
   1.311 +				pRawProfile,pRawTime);
   1.312 +    if (rv != SECSuccess) {
   1.313 +	ck_rv = CKR_DEVICE_ERROR;
   1.314 +	goto loser;
   1.315 +    }
   1.316 +    emailKey.data = (unsigned char *)email;
   1.317 +    emailKey.len = PORT_Strlen(email)+1;
   1.318 +
   1.319 +    *handle = lg_mkHandle(sdb, &emailKey, LG_TOKEN_TYPE_SMIME);
   1.320 +
   1.321 +loser:
   1.322 +    if (email)   PORT_Free(email);
   1.323 +
   1.324 +    return ck_rv;
   1.325 +}
   1.326 +
   1.327 +/*
   1.328 + * check the consistancy and initialize a Trust Object 
   1.329 + */
   1.330 +static CK_RV
   1.331 +lg_createCrlObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
   1.332 +			const CK_ATTRIBUTE *templ, CK_ULONG count)
   1.333 +{
   1.334 +    PRBool isKRL = PR_FALSE;
   1.335 +    SECItem derSubj,derCrl;
   1.336 +    char *url = NULL;
   1.337 +    const CK_ATTRIBUTE *subject,*crl;
   1.338 +    SECStatus rv;
   1.339 +    NSSLOWCERTCertDBHandle *certHandle;
   1.340 +
   1.341 +    certHandle = lg_getCertDB(sdb);
   1.342 +
   1.343 +    /* we can't store any private crls */
   1.344 +    if (lg_isTrue(CKA_PRIVATE,templ,count)) {
   1.345 +	return CKR_ATTRIBUTE_VALUE_INVALID;
   1.346 +    }
   1.347 +
   1.348 +    if (certHandle == NULL) {
   1.349 +	return CKR_TOKEN_WRITE_PROTECTED;
   1.350 +    }
   1.351 +
   1.352 +    /* lookup SUBJECT */
   1.353 +    subject = lg_FindAttribute(CKA_SUBJECT,templ,count);
   1.354 +    if (!subject) {
   1.355 +	 return CKR_ATTRIBUTE_VALUE_INVALID;
   1.356 +    }
   1.357 +
   1.358 +    derSubj.data = (unsigned char *)subject->pValue;
   1.359 +    derSubj.len = subject->ulValueLen ;
   1.360 +
   1.361 +    /* lookup VALUE */
   1.362 +    crl = lg_FindAttribute(CKA_VALUE,templ,count);
   1.363 +    PORT_Assert(crl);
   1.364 +    if (!crl) {
   1.365 +	 return CKR_ATTRIBUTE_VALUE_INVALID;
   1.366 +    }
   1.367 +    derCrl.data = (unsigned char *)crl->pValue;
   1.368 +    derCrl.len = crl->ulValueLen ;
   1.369 +
   1.370 +    url = lg_getString(CKA_NSS_URL,templ,count);
   1.371 +    isKRL = lg_isTrue(CKA_NSS_KRL,templ,count);
   1.372 +
   1.373 +    /* Store CRL by SUBJECT */
   1.374 +    rv = nsslowcert_AddCrl(certHandle, &derCrl, &derSubj, url, isKRL);
   1.375 +
   1.376 +    if (url) {
   1.377 +	PORT_Free(url);
   1.378 +    }
   1.379 +    if (rv != SECSuccess) {
   1.380 +	return CKR_DEVICE_ERROR;
   1.381 +    }
   1.382 +
   1.383 +    /* if we overwrote the existing CRL, poison the handle entry so we get
   1.384 +     * a new object handle */
   1.385 +    (void) lg_poisonHandle(sdb, &derSubj,
   1.386 +			isKRL ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL);
   1.387 +    *handle = lg_mkHandle(sdb, &derSubj,
   1.388 +			isKRL ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL);
   1.389 +
   1.390 +    return CKR_OK;
   1.391 +}
   1.392 +
   1.393 +/*
   1.394 + * check the consistancy and initialize a Public Key Object 
   1.395 + */
   1.396 +static CK_RV
   1.397 +lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
   1.398 +     CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
   1.399 +{
   1.400 +    CK_ATTRIBUTE_TYPE pubKeyAttr = CKA_VALUE;
   1.401 +    CK_RV crv = CKR_OK;
   1.402 +    NSSLOWKEYPrivateKey *priv;
   1.403 +    SECItem pubKeySpace = {siBuffer, NULL, 0};
   1.404 +    SECItem *pubKey;
   1.405 +#ifndef NSS_DISABLE_ECC
   1.406 +    SECItem pubKey2Space = {siBuffer, NULL, 0};
   1.407 +    PLArenaPool *arena = NULL;
   1.408 +#endif /* NSS_DISABLE_ECC */
   1.409 +    NSSLOWKEYDBHandle *keyHandle = NULL;
   1.410 +	
   1.411 +
   1.412 +    switch (key_type) {
   1.413 +    case CKK_RSA:
   1.414 +	pubKeyAttr = CKA_MODULUS;
   1.415 +	break;
   1.416 +#ifndef NSS_DISABLE_ECC
   1.417 +    case CKK_EC:
   1.418 +	pubKeyAttr = CKA_EC_POINT;
   1.419 +	break;
   1.420 +#endif /* NSS_DISABLE_ECC */
   1.421 +    case CKK_DSA:
   1.422 +    case CKK_DH:
   1.423 +	break;
   1.424 +    default:
   1.425 +	return CKR_ATTRIBUTE_VALUE_INVALID;
   1.426 +    }
   1.427 +
   1.428 +
   1.429 +    pubKey = &pubKeySpace;
   1.430 +    crv = lg_Attribute2SSecItem(NULL,pubKeyAttr,templ,count,pubKey);
   1.431 +    if (crv != CKR_OK) return crv;
   1.432 +
   1.433 +#ifndef NSS_DISABLE_ECC
   1.434 +    if (key_type == CKK_EC) {
   1.435 +	SECStatus rv;
   1.436 +	/*
   1.437 +	 * for ECC, use the decoded key first.
   1.438 +	 */
   1.439 +	arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
   1.440 +	if (arena == NULL) {
   1.441 +	    crv = CKR_HOST_MEMORY;
   1.442 +	    goto done;
   1.443 +	}
   1.444 +	rv= SEC_QuickDERDecodeItem(arena, &pubKey2Space, 
   1.445 +				   SEC_ASN1_GET(SEC_OctetStringTemplate), 
   1.446 +				   pubKey);
   1.447 +	if (rv != SECSuccess) {
   1.448 +	    /* decode didn't work, just try the pubKey */
   1.449 +	    PORT_FreeArena(arena, PR_FALSE);
   1.450 +	    arena = NULL;
   1.451 +	} else {
   1.452 +	    /* try the decoded pub key first */
   1.453 +	    pubKey = &pubKey2Space;
   1.454 +	}
   1.455 +    }
   1.456 +#endif /* NSS_DISABLE_ECC */
   1.457 +
   1.458 +    PORT_Assert(pubKey->data);
   1.459 +    if (pubKey->data == NULL) {
   1.460 +	crv = CKR_ATTRIBUTE_VALUE_INVALID;
   1.461 +	goto done;
   1.462 +    }
   1.463 +    keyHandle = lg_getKeyDB(sdb);
   1.464 +    if (keyHandle == NULL) {
   1.465 +	crv = CKR_TOKEN_WRITE_PROTECTED;
   1.466 +	goto done;
   1.467 +    }
   1.468 +    if (keyHandle->version != 3) {
   1.469 +	unsigned char buf[SHA1_LENGTH];
   1.470 +	SHA1_HashBuf(buf,pubKey->data,pubKey->len);
   1.471 +	PORT_Memcpy(pubKey->data,buf,sizeof(buf));
   1.472 +	pubKey->len = sizeof(buf);
   1.473 +    }
   1.474 +    /* make sure the associated private key already exists */
   1.475 +    /* only works if we are logged in */
   1.476 +    priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, sdb /*password*/);
   1.477 +#ifndef NSS_DISABLE_ECC
   1.478 +    if (priv == NULL && pubKey == &pubKey2Space) {
   1.479 +	/* no match on the decoded key, match the original pubkey */
   1.480 +	pubKey = &pubKeySpace;
   1.481 +    	priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, 
   1.482 +					    sdb /*password*/);
   1.483 +    }
   1.484 +#endif
   1.485 +    if (priv == NULL) {
   1.486 +	/* the legacy database can only 'store' public keys which already
   1.487 +	 * have their corresponding private keys in the database */
   1.488 +	crv = CKR_ATTRIBUTE_VALUE_INVALID;
   1.489 +	goto done;
   1.490 +    }
   1.491 +    lg_nsslowkey_DestroyPrivateKey(priv);
   1.492 +    crv = CKR_OK;
   1.493 +
   1.494 +    *handle = lg_mkHandle(sdb, pubKey, LG_TOKEN_TYPE_PUB);
   1.495 +
   1.496 +done:
   1.497 +    PORT_Free(pubKeySpace.data);
   1.498 +#ifndef NSS_DISABLE_ECC
   1.499 +    if (arena) 
   1.500 +	PORT_FreeArena(arena, PR_FALSE);
   1.501 +#endif
   1.502 +
   1.503 +    return crv;
   1.504 +}
   1.505 +
   1.506 +/* make a private key from a verified object */
   1.507 +static NSSLOWKEYPrivateKey *
   1.508 +lg_mkPrivKey(SDB *sdb, const CK_ATTRIBUTE *templ, CK_ULONG count,
   1.509 +	     CK_KEY_TYPE key_type, CK_RV *crvp)
   1.510 +{
   1.511 +    NSSLOWKEYPrivateKey *privKey;
   1.512 +    PLArenaPool *arena;
   1.513 +    CK_RV crv = CKR_OK;
   1.514 +    SECStatus rv;
   1.515 +
   1.516 +    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
   1.517 +    if (arena == NULL) {
   1.518 +	*crvp = CKR_HOST_MEMORY;
   1.519 +	return NULL;
   1.520 +    }
   1.521 +
   1.522 +    privKey = (NSSLOWKEYPrivateKey *)
   1.523 +			PORT_ArenaZAlloc(arena,sizeof(NSSLOWKEYPrivateKey));
   1.524 +    if (privKey == NULL)  {
   1.525 +	PORT_FreeArena(arena,PR_FALSE);
   1.526 +	*crvp = CKR_HOST_MEMORY;
   1.527 +	return NULL;
   1.528 +    }
   1.529 +
   1.530 +    /* in future this would be a switch on key_type */
   1.531 +    privKey->arena = arena;
   1.532 +    switch (key_type) {
   1.533 +    case CKK_RSA:
   1.534 +	privKey->keyType = NSSLOWKEYRSAKey;
   1.535 +	crv=lg_Attribute2SSecItem(arena,CKA_MODULUS,templ,count,
   1.536 +					&privKey->u.rsa.modulus);
   1.537 +	if (crv != CKR_OK) break;
   1.538 +	crv=lg_Attribute2SSecItem(arena,CKA_PUBLIC_EXPONENT,templ,count,
   1.539 +					&privKey->u.rsa.publicExponent);
   1.540 +	if (crv != CKR_OK) break;
   1.541 +	crv=lg_PrivAttr2SSecItem(arena,CKA_PRIVATE_EXPONENT,templ,count,
   1.542 +				&privKey->u.rsa.privateExponent, sdb);
   1.543 +	if (crv != CKR_OK) break;
   1.544 +	crv=lg_PrivAttr2SSecItem(arena,CKA_PRIME_1,templ,count,
   1.545 +					&privKey->u.rsa.prime1, sdb);
   1.546 +	if (crv != CKR_OK) break;
   1.547 +	crv=lg_PrivAttr2SSecItem(arena,CKA_PRIME_2,templ,count,
   1.548 +					&privKey->u.rsa.prime2, sdb);
   1.549 +	if (crv != CKR_OK) break;
   1.550 +	crv=lg_PrivAttr2SSecItem(arena,CKA_EXPONENT_1,templ,count,
   1.551 +					&privKey->u.rsa.exponent1, sdb);
   1.552 +	if (crv != CKR_OK) break;
   1.553 +	crv=lg_PrivAttr2SSecItem(arena,CKA_EXPONENT_2,templ,count,
   1.554 +					&privKey->u.rsa.exponent2, sdb);
   1.555 +	if (crv != CKR_OK) break;
   1.556 +	crv=lg_PrivAttr2SSecItem(arena,CKA_COEFFICIENT,templ,count,
   1.557 +					&privKey->u.rsa.coefficient, sdb);
   1.558 +	if (crv != CKR_OK) break;
   1.559 +        rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version,
   1.560 +                          NSSLOWKEY_VERSION);
   1.561 +	if (rv != SECSuccess) crv = CKR_HOST_MEMORY;
   1.562 +	break;
   1.563 +
   1.564 +    case CKK_DSA:
   1.565 +	privKey->keyType = NSSLOWKEYDSAKey;
   1.566 +	crv = lg_Attribute2SSecItem(arena,CKA_PRIME,templ,count,
   1.567 +					&privKey->u.dsa.params.prime);
   1.568 +    	if (crv != CKR_OK) break;
   1.569 +	crv = lg_Attribute2SSecItem(arena,CKA_SUBPRIME,templ,count,
   1.570 +					&privKey->u.dsa.params.subPrime);
   1.571 +    	if (crv != CKR_OK) break;
   1.572 +	crv = lg_Attribute2SSecItem(arena,CKA_BASE,templ,count,
   1.573 +					&privKey->u.dsa.params.base);
   1.574 +    	if (crv != CKR_OK) break;
   1.575 +    	crv = lg_PrivAttr2SSecItem(arena,CKA_VALUE,templ,count,
   1.576 +					&privKey->u.dsa.privateValue, sdb);
   1.577 +    	if (crv != CKR_OK) break;
   1.578 +	if (lg_hasAttribute(CKA_NETSCAPE_DB, templ,count)) {
   1.579 +	    crv = lg_Attribute2SSecItem(arena, CKA_NETSCAPE_DB,templ,count,
   1.580 +						&privKey->u.dsa.publicValue);
   1.581 +	    /* privKey was zero'd so public value is already set to NULL, 0
   1.582 +	     * if we don't set it explicitly */
   1.583 +	}
   1.584 +	break;
   1.585 +
   1.586 +    case CKK_DH:
   1.587 +	privKey->keyType = NSSLOWKEYDHKey;
   1.588 +	crv = lg_Attribute2SSecItem(arena,CKA_PRIME,templ,count,
   1.589 +					&privKey->u.dh.prime);
   1.590 +    	if (crv != CKR_OK) break;
   1.591 +	crv = lg_Attribute2SSecItem(arena,CKA_BASE,templ,count,
   1.592 +					&privKey->u.dh.base);
   1.593 +    	if (crv != CKR_OK) break;
   1.594 +    	crv = lg_PrivAttr2SSecItem(arena,CKA_VALUE,templ,count,
   1.595 +					&privKey->u.dh.privateValue, sdb);
   1.596 +    	if (crv != CKR_OK) break;
   1.597 +	if (lg_hasAttribute(CKA_NETSCAPE_DB, templ, count)) {
   1.598 +	    crv = lg_Attribute2SSecItem(arena, CKA_NETSCAPE_DB,templ,count,
   1.599 +					&privKey->u.dh.publicValue);
   1.600 +	    /* privKey was zero'd so public value is already set to NULL, 0
   1.601 +	     * if we don't set it explicitly */
   1.602 +	}
   1.603 +	break;
   1.604 +
   1.605 +#ifndef NSS_DISABLE_ECC
   1.606 +    case CKK_EC:
   1.607 +	privKey->keyType = NSSLOWKEYECKey;
   1.608 +	crv = lg_Attribute2SSecItem(arena, CKA_EC_PARAMS,templ,count,
   1.609 +	                              &privKey->u.ec.ecParams.DEREncoding);
   1.610 +    	if (crv != CKR_OK) break;
   1.611 +
   1.612 +	/* Fill out the rest of the ecParams structure
   1.613 +	 * based on the encoded params
   1.614 +	 */
   1.615 +	if (LGEC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding,
   1.616 +		    &privKey->u.ec.ecParams) != SECSuccess) {
   1.617 +	    crv = CKR_DOMAIN_PARAMS_INVALID;
   1.618 +	    break;
   1.619 +	}
   1.620 +	crv = lg_PrivAttr2SSecItem(arena,CKA_VALUE,templ,count,
   1.621 +					&privKey->u.ec.privateValue, sdb);
   1.622 +	if (crv != CKR_OK) break;
   1.623 +	if (lg_hasAttribute(CKA_NETSCAPE_DB,templ,count)) {
   1.624 +	    crv = lg_Attribute2SSecItem(arena, CKA_NETSCAPE_DB,templ,count,
   1.625 +					&privKey->u.ec.publicValue);
   1.626 +	    if (crv != CKR_OK) break;
   1.627 +	    /* privKey was zero'd so public value is already set to NULL, 0
   1.628 +	     * if we don't set it explicitly */
   1.629 +	}
   1.630 +        rv = DER_SetUInteger(privKey->arena, &privKey->u.ec.version,
   1.631 +                          NSSLOWKEY_EC_PRIVATE_KEY_VERSION);
   1.632 +	if (rv != SECSuccess) crv = CKR_HOST_MEMORY;
   1.633 +	break;
   1.634 +#endif /* NSS_DISABLE_ECC */
   1.635 +
   1.636 +    default:
   1.637 +	crv = CKR_KEY_TYPE_INCONSISTENT;
   1.638 +	break;
   1.639 +    }
   1.640 +    *crvp = crv;
   1.641 +    if (crv != CKR_OK) {
   1.642 +	PORT_FreeArena(arena,PR_FALSE);
   1.643 +	return NULL;
   1.644 +    }
   1.645 +    return privKey;
   1.646 +}
   1.647 +
   1.648 +/*
   1.649 + * check the consistancy and initialize a Private Key Object 
   1.650 + */
   1.651 +static CK_RV
   1.652 +lg_createPrivateKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
   1.653 +     CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
   1.654 +{
   1.655 +    NSSLOWKEYPrivateKey *privKey;
   1.656 +    char *label;
   1.657 +    SECStatus rv = SECSuccess;
   1.658 +    CK_RV crv = CKR_DEVICE_ERROR;
   1.659 +    SECItem pubKey;
   1.660 +    NSSLOWKEYDBHandle *keyHandle = lg_getKeyDB(sdb);
   1.661 +
   1.662 +    if (keyHandle == NULL) {
   1.663 +	return CKR_TOKEN_WRITE_PROTECTED;
   1.664 +    }
   1.665 +
   1.666 +    privKey=lg_mkPrivKey(sdb, templ,count,key_type,&crv);
   1.667 +    if (privKey == NULL) return crv;
   1.668 +    label = lg_getString(CKA_LABEL,templ,count);
   1.669 +
   1.670 +    crv = lg_Attribute2SSecItem(NULL,CKA_NETSCAPE_DB,templ,count,&pubKey);
   1.671 +    if (crv != CKR_OK) {
   1.672 +	crv = CKR_TEMPLATE_INCOMPLETE;
   1.673 +	rv = SECFailure;
   1.674 +	goto fail;
   1.675 +    }
   1.676 +#ifdef notdef
   1.677 +    if (keyHandle->version != 3) {
   1.678 +	unsigned char buf[SHA1_LENGTH];
   1.679 +	SHA1_HashBuf(buf,pubKey.data,pubKey.len);
   1.680 +	PORT_Memcpy(pubKey.data,buf,sizeof(buf));
   1.681 +	pubKey.len = sizeof(buf);
   1.682 +    }
   1.683 +#endif
   1.684 +    /* get the key type */
   1.685 +    if (key_type == CKK_RSA) {
   1.686 +	rv = RSA_PrivateKeyCheck(&privKey->u.rsa);
   1.687 +	if (rv == SECFailure) {
   1.688 +	    goto fail;
   1.689 +	}
   1.690 +    }
   1.691 +    rv = nsslowkey_StoreKeyByPublicKey(keyHandle, privKey, &pubKey, 
   1.692 +					   label, sdb /*->password*/);
   1.693 +
   1.694 +fail:
   1.695 +    if (label) PORT_Free(label);
   1.696 +    *handle = lg_mkHandle(sdb,&pubKey,LG_TOKEN_TYPE_PRIV);
   1.697 +    if (pubKey.data) PORT_Free(pubKey.data);
   1.698 +    lg_nsslowkey_DestroyPrivateKey(privKey);
   1.699 +    if (rv != SECSuccess) return crv;
   1.700 +
   1.701 +    return CKR_OK;
   1.702 +}
   1.703 +
   1.704 +
   1.705 +#define LG_KEY_MAX_RETRIES 10 /* don't hang if we are having problems with the rng */
   1.706 +#define LG_KEY_ID_SIZE 18 /* don't use either SHA1 or MD5 sizes */
   1.707 +/*
   1.708 + * Secret keys must have a CKA_ID value to be stored in the database. This code
   1.709 + * will generate one if there wasn't one already. 
   1.710 + */
   1.711 +static CK_RV
   1.712 +lg_GenerateSecretCKA_ID(NSSLOWKEYDBHandle *handle, SECItem *id, char *label)
   1.713 +{
   1.714 +    unsigned int retries;
   1.715 +    SECStatus rv = SECSuccess;
   1.716 +    CK_RV crv = CKR_OK;
   1.717 +
   1.718 +    id->data = NULL;
   1.719 +    if (label) {
   1.720 +	id->data = (unsigned char *)PORT_Strdup(label);
   1.721 +	if (id->data == NULL) {
   1.722 +	    return CKR_HOST_MEMORY;
   1.723 +	}
   1.724 +	id->len = PORT_Strlen(label)+1;
   1.725 +	if (!nsslowkey_KeyForIDExists(handle,id)) { 
   1.726 +	    return CKR_OK;
   1.727 +	}
   1.728 +	PORT_Free(id->data);
   1.729 +	id->data = NULL;
   1.730 +	id->len = 0;
   1.731 +    }
   1.732 +    id->data = (unsigned char *)PORT_Alloc(LG_KEY_ID_SIZE);
   1.733 +    if (id->data == NULL) {
   1.734 +	return CKR_HOST_MEMORY;
   1.735 +    }
   1.736 +    id->len = LG_KEY_ID_SIZE;
   1.737 +
   1.738 +    retries = 0;
   1.739 +    do {
   1.740 +	rv = RNG_GenerateGlobalRandomBytes(id->data,id->len);
   1.741 +    } while (rv == SECSuccess && nsslowkey_KeyForIDExists(handle,id) && 
   1.742 +				(++retries <= LG_KEY_MAX_RETRIES));
   1.743 +
   1.744 +    if ((rv != SECSuccess) || (retries > LG_KEY_MAX_RETRIES)) {
   1.745 +	crv = CKR_DEVICE_ERROR; /* random number generator is bad */
   1.746 +	PORT_Free(id->data);
   1.747 +	id->data = NULL;
   1.748 +	id->len = 0;
   1.749 +    }
   1.750 +    return crv;
   1.751 +}
   1.752 +
   1.753 +
   1.754 +static NSSLOWKEYPrivateKey *lg_mkSecretKeyRep(const CK_ATTRIBUTE *templ,
   1.755 +		 CK_ULONG count, CK_KEY_TYPE key_type, 
   1.756 +		 SECItem *pubkey, SDB *sdbpw)
   1.757 +{
   1.758 +    NSSLOWKEYPrivateKey *privKey = 0;
   1.759 +    PLArenaPool *arena = 0;
   1.760 +    CK_KEY_TYPE keyType;
   1.761 +    PRUint32 keyTypeStorage;
   1.762 +    SECItem keyTypeItem;
   1.763 +    CK_RV crv;
   1.764 +    SECStatus rv;
   1.765 +    static unsigned char derZero[1] = { 0 };
   1.766 +
   1.767 +    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
   1.768 +    if (arena == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
   1.769 +
   1.770 +    privKey = (NSSLOWKEYPrivateKey *)
   1.771 +			PORT_ArenaZAlloc(arena,sizeof(NSSLOWKEYPrivateKey));
   1.772 +    if (privKey == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
   1.773 +
   1.774 +    privKey->arena = arena;
   1.775 +
   1.776 +    /* Secret keys are represented in the database as "fake" RSA keys.  
   1.777 +     * The RSA key is marked as a secret key representation by setting the 
   1.778 +     * public exponent field to 0, which is an invalid RSA exponent.  
   1.779 +     * The other fields are set as follows:
   1.780 +     *   modulus - CKA_ID value for the secret key
   1.781 +     *   private exponent - CKA_VALUE (the key itself)
   1.782 +     *   coefficient - CKA_KEY_TYPE, which indicates what encryption algorithm
   1.783 +     *      is used for the key.
   1.784 +     *   all others - set to integer 0
   1.785 +     */
   1.786 +    privKey->keyType = NSSLOWKEYRSAKey;
   1.787 +
   1.788 +    /* The modulus is set to the key id of the symmetric key */
   1.789 +    privKey->u.rsa.modulus.data =
   1.790 +		(unsigned char *) PORT_ArenaAlloc(arena, pubkey->len);
   1.791 +    if (privKey->u.rsa.modulus.data == NULL) {
   1.792 +	crv = CKR_HOST_MEMORY;
   1.793 +	goto loser;
   1.794 +    }
   1.795 +    privKey->u.rsa.modulus.len = pubkey->len;
   1.796 +    PORT_Memcpy(privKey->u.rsa.modulus.data, pubkey->data, pubkey->len);
   1.797 +
   1.798 +    /* The public exponent is set to 0 to indicate a special key */
   1.799 +    privKey->u.rsa.publicExponent.len = sizeof derZero;
   1.800 +    privKey->u.rsa.publicExponent.data = derZero;
   1.801 +
   1.802 +    /* The private exponent is the actual key value */
   1.803 +    crv = lg_PrivAttr2SecItem(arena, CKA_VALUE, templ, count,
   1.804 +				&privKey->u.rsa.privateExponent, sdbpw);
   1.805 +    if (crv != CKR_OK) goto loser;
   1.806 +
   1.807 +    /* All other fields empty - needs testing */
   1.808 +    privKey->u.rsa.prime1.len = sizeof derZero;
   1.809 +    privKey->u.rsa.prime1.data = derZero;
   1.810 +
   1.811 +    privKey->u.rsa.prime2.len = sizeof derZero;
   1.812 +    privKey->u.rsa.prime2.data = derZero;
   1.813 +
   1.814 +    privKey->u.rsa.exponent1.len = sizeof derZero;
   1.815 +    privKey->u.rsa.exponent1.data = derZero;
   1.816 +
   1.817 +    privKey->u.rsa.exponent2.len = sizeof derZero;
   1.818 +    privKey->u.rsa.exponent2.data = derZero;
   1.819 +
   1.820 +    /* Coeficient set to KEY_TYPE */
   1.821 +    crv = lg_GetULongAttribute(CKA_KEY_TYPE, templ, count, &keyType);
   1.822 +    if (crv != CKR_OK) goto loser; 
   1.823 +    /* on 64 bit platforms, we still want to store 32 bits of keyType (This is
   1.824 +     * safe since the PKCS #11 defines for all types are 32 bits or less). */
   1.825 +    keyTypeStorage = (PRUint32) keyType;
   1.826 +    keyTypeStorage = PR_htonl(keyTypeStorage);
   1.827 +    keyTypeItem.data = (unsigned char *)&keyTypeStorage;
   1.828 +    keyTypeItem.len = sizeof (keyTypeStorage);
   1.829 +    rv = SECITEM_CopyItem(arena, &privKey->u.rsa.coefficient, &keyTypeItem);
   1.830 +    if (rv != SECSuccess) {
   1.831 +	crv = CKR_HOST_MEMORY;
   1.832 +	goto loser;
   1.833 +    }
   1.834 +    
   1.835 +    /* Private key version field set normally for compatibility */
   1.836 +    rv = DER_SetUInteger(privKey->arena, 
   1.837 +			&privKey->u.rsa.version, NSSLOWKEY_VERSION);
   1.838 +    if (rv != SECSuccess) { crv = CKR_HOST_MEMORY; goto loser; }
   1.839 +
   1.840 +loser:
   1.841 +    if (crv != CKR_OK) {
   1.842 +	PORT_FreeArena(arena,PR_FALSE);
   1.843 +	privKey = 0;
   1.844 +    }
   1.845 +
   1.846 +    return privKey;
   1.847 +}
   1.848 +
   1.849 +/*
   1.850 + * check the consistancy and initialize a Secret Key Object 
   1.851 + */
   1.852 +static CK_RV
   1.853 +lg_createSecretKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
   1.854 +     CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
   1.855 +{
   1.856 +    CK_RV crv;
   1.857 +    NSSLOWKEYPrivateKey *privKey   = NULL;
   1.858 +    NSSLOWKEYDBHandle   *keyHandle = NULL;
   1.859 +    SECItem pubKey;
   1.860 +    char *label = NULL;
   1.861 +    SECStatus rv = SECSuccess;
   1.862 +
   1.863 +    pubKey.data = 0;
   1.864 +
   1.865 +    /* If the object is a TOKEN object, store in the database */
   1.866 +    keyHandle = lg_getKeyDB(sdb);
   1.867 +
   1.868 +    if (keyHandle == NULL) {
   1.869 +	return CKR_TOKEN_WRITE_PROTECTED;
   1.870 +    }
   1.871 +
   1.872 +    label = lg_getString(CKA_LABEL,templ,count);
   1.873 +
   1.874 +    crv = lg_Attribute2SecItem(NULL,CKA_ID,templ,count,&pubKey);
   1.875 +						/* Should this be ID? */
   1.876 +    if (crv != CKR_OK) goto loser;
   1.877 +
   1.878 +    /* if we don't have an ID, generate one */
   1.879 +    if (pubKey.len == 0) {
   1.880 +	if (pubKey.data) { 
   1.881 +	    PORT_Free(pubKey.data);
   1.882 +	    pubKey.data = NULL;
   1.883 +	}
   1.884 +	crv = lg_GenerateSecretCKA_ID(keyHandle, &pubKey, label);
   1.885 +	if (crv != CKR_OK) goto loser;
   1.886 +    }
   1.887 +
   1.888 +    privKey = lg_mkSecretKeyRep(templ, count, key_type, &pubKey, sdb);
   1.889 +    if (privKey == NULL) {
   1.890 +	crv = CKR_HOST_MEMORY;
   1.891 +	goto loser;
   1.892 +    }
   1.893 +
   1.894 +    rv = nsslowkey_StoreKeyByPublicKey(keyHandle,
   1.895 +			privKey, &pubKey, label, sdb /*->password*/);
   1.896 +    if (rv != SECSuccess) {
   1.897 +	crv = CKR_DEVICE_ERROR;
   1.898 +	goto loser;
   1.899 +    }
   1.900 +
   1.901 +    *handle = lg_mkHandle(sdb, &pubKey, LG_TOKEN_TYPE_KEY);
   1.902 +
   1.903 +loser:
   1.904 +    if (label) PORT_Free(label);
   1.905 +    if (privKey) lg_nsslowkey_DestroyPrivateKey(privKey);
   1.906 +    if (pubKey.data) PORT_Free(pubKey.data);
   1.907 +
   1.908 +    return crv;
   1.909 +}
   1.910 +
   1.911 +/*
   1.912 + * check the consistancy and initialize a Key Object 
   1.913 + */
   1.914 +static CK_RV
   1.915 +lg_createKeyObject(SDB *sdb, CK_OBJECT_CLASS objclass, 
   1.916 +	CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
   1.917 +{
   1.918 +    CK_RV crv;
   1.919 +    CK_KEY_TYPE key_type;
   1.920 +
   1.921 +    /* get the key type */
   1.922 +    crv = lg_GetULongAttribute(CKA_KEY_TYPE, templ, count, &key_type);
   1.923 +    if (crv != CKR_OK) {
   1.924 +	return crv;
   1.925 +    }
   1.926 +
   1.927 +    switch (objclass) {
   1.928 +    case CKO_PUBLIC_KEY:
   1.929 +	return lg_createPublicKeyObject(sdb,key_type,handle,templ,count);
   1.930 +    case CKO_PRIVATE_KEY:
   1.931 +	return lg_createPrivateKeyObject(sdb,key_type,handle,templ,count);
   1.932 +    case CKO_SECRET_KEY:
   1.933 +	return lg_createSecretKeyObject(sdb,key_type,handle,templ,count);
   1.934 +    default:
   1.935 +	break;
   1.936 +    }
   1.937 +    return CKR_ATTRIBUTE_VALUE_INVALID;
   1.938 +}
   1.939 +
   1.940 +/* 
   1.941 + * Parse the template and create an object stored in the DB that reflects.
   1.942 + * the object specified in the database.
   1.943 + */
   1.944 +CK_RV
   1.945 +lg_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
   1.946 +			const CK_ATTRIBUTE *templ, CK_ULONG count)
   1.947 +{
   1.948 +    CK_RV crv;
   1.949 +    CK_OBJECT_CLASS objclass;
   1.950 +
   1.951 +    /* get the object class */
   1.952 +    crv = lg_GetULongAttribute(CKA_CLASS, templ, count, &objclass);
   1.953 +    if (crv != CKR_OK) {
   1.954 +	return crv;
   1.955 +    }
   1.956 +
   1.957 +    /* Now handle the specific object class. 
   1.958 +     */
   1.959 +    switch (objclass) {
   1.960 +    case CKO_CERTIFICATE:
   1.961 +	crv = lg_createCertObject(sdb,handle,templ,count);
   1.962 +	break;
   1.963 +    case CKO_NSS_TRUST:
   1.964 +	crv = lg_createTrustObject(sdb,handle,templ,count);
   1.965 +	break;
   1.966 +    case CKO_NSS_CRL:
   1.967 +	crv = lg_createCrlObject(sdb,handle,templ,count);
   1.968 +	break;
   1.969 +    case CKO_NSS_SMIME:
   1.970 +	crv = lg_createSMimeObject(sdb,handle,templ,count);
   1.971 +	break;
   1.972 +    case CKO_PRIVATE_KEY:
   1.973 +    case CKO_PUBLIC_KEY:
   1.974 +    case CKO_SECRET_KEY:
   1.975 +	crv = lg_createKeyObject(sdb,objclass,handle,templ,count);
   1.976 +	break;
   1.977 +    default:
   1.978 +	crv = CKR_ATTRIBUTE_VALUE_INVALID;
   1.979 +	break;
   1.980 +    }
   1.981 +
   1.982 +    return crv;
   1.983 +}
   1.984 +

mercurial