Back to index

lightning-sunbird  0.9+nobinonly
ckhelper.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #ifdef DEBUG
00038 static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.34 $ $Date: 2005/04/04 18:46:23 $";
00039 #endif /* DEBUG */
00040 
00041 #ifndef NSSCKEPV_H
00042 #include "nssckepv.h"
00043 #endif /* NSSCKEPV_H */
00044 
00045 #ifndef DEVM_H
00046 #include "devm.h"
00047 #endif /* DEVM_H */
00048 
00049 #ifndef CKHELPER_H
00050 #include "ckhelper.h"
00051 #endif /* CKHELPER_H */
00052 
00053 extern const NSSError NSS_ERROR_DEVICE_ERROR;
00054 
00055 static const CK_BBOOL s_true = CK_TRUE;
00056 NSS_IMPLEMENT_DATA const NSSItem
00057 g_ck_true = { (CK_VOID_PTR)&s_true, sizeof(s_true) };
00058 
00059 static const CK_BBOOL s_false = CK_FALSE;
00060 NSS_IMPLEMENT_DATA const NSSItem
00061 g_ck_false = { (CK_VOID_PTR)&s_false, sizeof(s_false) };
00062 
00063 static const CK_OBJECT_CLASS s_class_cert = CKO_CERTIFICATE;
00064 NSS_IMPLEMENT_DATA const NSSItem
00065 g_ck_class_cert = { (CK_VOID_PTR)&s_class_cert, sizeof(s_class_cert) };
00066 
00067 static const CK_OBJECT_CLASS s_class_pubkey = CKO_PUBLIC_KEY;
00068 NSS_IMPLEMENT_DATA const NSSItem
00069 g_ck_class_pubkey = { (CK_VOID_PTR)&s_class_pubkey, sizeof(s_class_pubkey) };
00070 
00071 static const CK_OBJECT_CLASS s_class_privkey = CKO_PRIVATE_KEY;
00072 NSS_IMPLEMENT_DATA const NSSItem
00073 g_ck_class_privkey = { (CK_VOID_PTR)&s_class_privkey, sizeof(s_class_privkey) };
00074 
00075 static PRBool
00076 is_string_attribute (
00077   CK_ATTRIBUTE_TYPE aType
00078 )
00079 {
00080     PRBool isString;
00081     switch (aType) {
00082     case CKA_LABEL:
00083     case CKA_NETSCAPE_EMAIL:
00084        isString = PR_TRUE;
00085        break;
00086     default:
00087        isString = PR_FALSE;
00088        break;
00089     }
00090     return isString;
00091 }
00092 
00093 NSS_IMPLEMENT PRStatus 
00094 nssCKObject_GetAttributes (
00095   CK_OBJECT_HANDLE object,
00096   CK_ATTRIBUTE_PTR obj_template,
00097   CK_ULONG count,
00098   NSSArena *arenaOpt,
00099   nssSession *session,
00100   NSSSlot *slot
00101 )
00102 {
00103     nssArenaMark *mark = NULL;
00104     CK_SESSION_HANDLE hSession;
00105     CK_ULONG i = 0;
00106     CK_RV ckrv;
00107     PRStatus nssrv;
00108     PRBool alloced = PR_FALSE;
00109     void *epv = nssSlot_GetCryptokiEPV(slot);
00110     hSession = session->handle; 
00111     if (arenaOpt) {
00112        mark = nssArena_Mark(arenaOpt);
00113        if (!mark) {
00114            goto loser;
00115        }
00116     }
00117     nssSession_EnterMonitor(session);
00118     /* XXX kinda hacky, if the storage size is already in the first template
00119      * item, then skip the alloc portion
00120      */
00121     if (obj_template[0].ulValueLen == 0) {
00122        /* Get the storage size needed for each attribute */
00123        ckrv = CKAPI(epv)->C_GetAttributeValue(hSession,
00124                                               object, obj_template, count);
00125        if (ckrv != CKR_OK && 
00126            ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
00127            ckrv != CKR_ATTRIBUTE_SENSITIVE) 
00128        {
00129            nssSession_ExitMonitor(session);
00130            nss_SetError(NSS_ERROR_DEVICE_ERROR);
00131            goto loser;
00132        }
00133        /* Allocate memory for each attribute. */
00134        for (i=0; i<count; i++) {
00135            CK_ULONG ulValueLen = obj_template[i].ulValueLen;
00136            if (ulValueLen == 0) continue;
00137            if (ulValueLen == (CK_ULONG) -1) {
00138               obj_template[i].ulValueLen = 0;
00139               continue;
00140            }
00141            if (is_string_attribute(obj_template[i].type)) {
00142               ulValueLen++;
00143            }
00144            obj_template[i].pValue = nss_ZAlloc(arenaOpt, ulValueLen);
00145            if (!obj_template[i].pValue) {
00146               nssSession_ExitMonitor(session);
00147               goto loser;
00148            }
00149        }
00150        alloced = PR_TRUE;
00151     }
00152     /* Obtain the actual attribute values. */
00153     ckrv = CKAPI(epv)->C_GetAttributeValue(hSession,
00154                                            object, obj_template, count);
00155     nssSession_ExitMonitor(session);
00156     if (ckrv != CKR_OK && 
00157         ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
00158         ckrv != CKR_ATTRIBUTE_SENSITIVE) 
00159     {
00160        nss_SetError(NSS_ERROR_DEVICE_ERROR);
00161        goto loser;
00162     }
00163     if (alloced && arenaOpt) {
00164        nssrv = nssArena_Unmark(arenaOpt, mark);
00165        if (nssrv != PR_SUCCESS) {
00166            goto loser;
00167        }
00168     }
00169 
00170     if (count > 1 && ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) || 
00171                                    (ckrv == CKR_ATTRIBUTE_SENSITIVE))) {
00172        /* old tokens would keep the length of '0' and not deal with any
00173         * of the attributes we passed. For those tokens read them one at
00174         * a time */
00175        for (i=0; i < count; i++) {
00176            if ((obj_template[i].ulValueLen == 0) 
00177                             || (obj_template[i].ulValueLen == -1)) {
00178               obj_template[i].ulValueLen=0;
00179               (void) nssCKObject_GetAttributes(object,&obj_template[i], 1,
00180                      arenaOpt, session, slot);
00181            }
00182        }
00183     }
00184     return PR_SUCCESS;
00185 loser:
00186     if (alloced) {
00187        if (arenaOpt) {
00188            /* release all arena memory allocated before the failure. */
00189            (void)nssArena_Release(arenaOpt, mark);
00190        } else {
00191            CK_ULONG j;
00192            /* free each heap object that was allocated before the failure. */
00193            for (j=0; j<i; j++) {
00194               nss_ZFreeIf(obj_template[j].pValue);
00195            }
00196        }
00197     }
00198     return PR_FAILURE;
00199 }
00200 
00201 NSS_IMPLEMENT PRStatus
00202 nssCKObject_GetAttributeItem (
00203   CK_OBJECT_HANDLE object,
00204   CK_ATTRIBUTE_TYPE attribute,
00205   NSSArena *arenaOpt,
00206   nssSession *session,
00207   NSSSlot *slot,
00208   NSSItem *rvItem
00209 )
00210 {
00211     CK_ATTRIBUTE attr = { 0, NULL, 0 };
00212     PRStatus nssrv;
00213     attr.type = attribute;
00214     nssrv = nssCKObject_GetAttributes(object, &attr, 1, 
00215                                       arenaOpt, session, slot);
00216     if (nssrv != PR_SUCCESS) {
00217        return nssrv;
00218     }
00219     rvItem->data = (void *)attr.pValue;
00220     rvItem->size = (PRUint32)attr.ulValueLen;
00221     return PR_SUCCESS;
00222 }
00223 
00224 NSS_IMPLEMENT PRBool
00225 nssCKObject_IsAttributeTrue (
00226   CK_OBJECT_HANDLE object,
00227   CK_ATTRIBUTE_TYPE attribute,
00228   nssSession *session,
00229   NSSSlot *slot,
00230   PRStatus *rvStatus
00231 )
00232 {
00233     CK_BBOOL bool;
00234     CK_ATTRIBUTE_PTR attr;
00235     CK_ATTRIBUTE atemplate = { 0, NULL, 0 };
00236     CK_RV ckrv;
00237     void *epv = nssSlot_GetCryptokiEPV(slot);
00238     attr = &atemplate;
00239     NSS_CK_SET_ATTRIBUTE_VAR(attr, attribute, bool);
00240     nssSession_EnterMonitor(session);
00241     ckrv = CKAPI(epv)->C_GetAttributeValue(session->handle, object, 
00242                                            &atemplate, 1);
00243     nssSession_ExitMonitor(session);
00244     if (ckrv != CKR_OK) {
00245        *rvStatus = PR_FAILURE;
00246        return PR_FALSE;
00247     }
00248     *rvStatus = PR_SUCCESS;
00249     return (PRBool)(bool == CK_TRUE);
00250 }
00251 
00252 NSS_IMPLEMENT PRStatus 
00253 nssCKObject_SetAttributes (
00254   CK_OBJECT_HANDLE object,
00255   CK_ATTRIBUTE_PTR obj_template,
00256   CK_ULONG count,
00257   nssSession *session,
00258   NSSSlot  *slot
00259 )
00260 {
00261     CK_RV ckrv;
00262     void *epv = nssSlot_GetCryptokiEPV(slot);
00263     nssSession_EnterMonitor(session);
00264     ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle, object, 
00265                                            obj_template, count);
00266     nssSession_ExitMonitor(session);
00267     if (ckrv == CKR_OK) {
00268        return PR_SUCCESS;
00269     } else {
00270        return PR_FAILURE;
00271     }
00272 }
00273 
00274 NSS_IMPLEMENT PRBool
00275 nssCKObject_IsTokenObjectTemplate (
00276   CK_ATTRIBUTE_PTR objectTemplate, 
00277   CK_ULONG otsize
00278 )
00279 {
00280     CK_ULONG ul;
00281     for (ul=0; ul<otsize; ul++) {
00282        if (objectTemplate[ul].type == CKA_TOKEN) {
00283            return (*((CK_BBOOL*)objectTemplate[ul].pValue) == CK_TRUE);
00284        }
00285     }
00286     return PR_FALSE;
00287 }
00288 
00289 static NSSCertificateType
00290 nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
00291 {
00292     CK_CERTIFICATE_TYPE ckCertType;
00293     if (!attrib->pValue) {
00294        /* default to PKIX */
00295        return NSSCertificateType_PKIX;
00296     }
00297     ckCertType = *((CK_ULONG *)attrib->pValue);
00298     switch (ckCertType) {
00299     case CKC_X_509:
00300        return NSSCertificateType_PKIX;
00301     default:
00302        break;
00303     }
00304     return NSSCertificateType_Unknown;
00305 }
00306 
00307 /* incoming pointers must be valid */
00308 NSS_IMPLEMENT PRStatus
00309 nssCryptokiCertificate_GetAttributes (
00310   nssCryptokiObject *certObject,
00311   nssSession *sessionOpt,
00312   NSSArena *arenaOpt,
00313   NSSCertificateType *certTypeOpt,
00314   NSSItem *idOpt,
00315   NSSDER *encodingOpt,
00316   NSSDER *issuerOpt,
00317   NSSDER *serialOpt,
00318   NSSDER *subjectOpt
00319 )
00320 {
00321     PRStatus status;
00322     PRUint32 i;
00323     nssSession *session;
00324     NSSSlot *slot;
00325     CK_ULONG template_size;
00326     CK_ATTRIBUTE_PTR attr;
00327     CK_ATTRIBUTE cert_template[6];
00328     /* Set up a template of all options chosen by caller */
00329     NSS_CK_TEMPLATE_START(cert_template, attr, template_size);
00330     if (certTypeOpt) {
00331        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CERTIFICATE_TYPE);
00332     }
00333     if (idOpt) {
00334        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
00335     }
00336     if (encodingOpt) {
00337        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
00338     }
00339     if (issuerOpt) {
00340        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ISSUER);
00341     }
00342     if (serialOpt) {
00343        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SERIAL_NUMBER);
00344     }
00345     if (subjectOpt) {
00346        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT);
00347     }
00348     NSS_CK_TEMPLATE_FINISH(cert_template, attr, template_size);
00349     if (template_size == 0) {
00350        /* caller didn't want anything */
00351        return PR_SUCCESS;
00352     }
00353 
00354     status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt,
00355                                                 certObject, CKO_CERTIFICATE,
00356                                                 cert_template, template_size);
00357     if (status != PR_SUCCESS) {
00358 
00359        session = sessionOpt ? 
00360                  sessionOpt : 
00361                  nssToken_GetDefaultSession(certObject->token);
00362 
00363        slot = nssToken_GetSlot(certObject->token);
00364        status = nssCKObject_GetAttributes(certObject->handle, 
00365                                           cert_template, template_size,
00366                                           arenaOpt, session, slot);
00367        nssSlot_Destroy(slot);
00368        if (status != PR_SUCCESS) {
00369            return status;
00370        }
00371     }
00372 
00373     i=0;
00374     if (certTypeOpt) {
00375        *certTypeOpt = nss_cert_type_from_ck_attrib(&cert_template[i]); i++;
00376     }
00377     if (idOpt) {
00378        NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], idOpt); i++;
00379     }
00380     if (encodingOpt) {
00381        NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], encodingOpt); i++;
00382     }
00383     if (issuerOpt) {
00384        NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], issuerOpt); i++;
00385     }
00386     if (serialOpt) {
00387        NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], serialOpt); i++;
00388     }
00389     if (subjectOpt) {
00390        NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], subjectOpt); i++;
00391     }
00392     return PR_SUCCESS;
00393 }
00394 
00395 #ifdef PURE_STAN_BUILD
00396 static NSSKeyPairType
00397 nss_key_pair_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
00398 {
00399     CK_KEY_TYPE ckKeyType;
00400     PR_ASSERT(attrib->pValue);
00401     ckKeyType = *((CK_ULONG *)attrib->pValue);
00402     switch (ckKeyType) {
00403     case CKK_RSA: return NSSKeyPairType_RSA;
00404     case CKK_DSA: return NSSKeyPairType_DSA;
00405     default: break;
00406     }
00407     return NSSKeyPairType_Unknown;
00408 }
00409 
00410 NSS_IMPLEMENT PRStatus
00411 nssCryptokiPrivateKey_GetAttributes (
00412   nssCryptokiObject *keyObject,
00413   nssSession *sessionOpt,
00414   NSSArena *arenaOpt,
00415   NSSKeyPairType *keyTypeOpt,
00416   NSSItem *idOpt
00417 )
00418 {
00419     PRStatus status;
00420     PRUint32 i;
00421     nssSession *session;
00422     NSSSlot *slot;
00423     CK_ULONG template_size;
00424     CK_ATTRIBUTE_PTR attr;
00425     CK_ATTRIBUTE key_template[2];
00426     /* Set up a template of all options chosen by caller */
00427     NSS_CK_TEMPLATE_START(key_template, attr, template_size);
00428     if (keyTypeOpt) {
00429        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_KEY_TYPE);
00430     }
00431     if (idOpt) {
00432        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
00433     }
00434     NSS_CK_TEMPLATE_FINISH(key_template, attr, template_size);
00435     if (template_size == 0) {
00436        /* caller didn't want anything */
00437        return PR_SUCCESS;
00438     }
00439 
00440     session = sessionOpt ? 
00441               sessionOpt : 
00442               nssToken_GetDefaultSession(keyObject->token);
00443 
00444     slot = nssToken_GetSlot(keyObject->token);
00445     status = nssCKObject_GetAttributes(keyObject->handle, 
00446                                        key_template, template_size,
00447                                        arenaOpt, session, slot);
00448     nssSlot_Destroy(slot);
00449     if (status != PR_SUCCESS) {
00450        return status;
00451     }
00452 
00453     i=0;
00454     if (keyTypeOpt) {
00455        *keyTypeOpt = nss_key_pair_type_from_ck_attrib(&key_template[i]); i++;
00456     }
00457     if (idOpt) {
00458        NSS_CK_ATTRIBUTE_TO_ITEM(&key_template[i], idOpt); i++;
00459     }
00460     return PR_SUCCESS;
00461 }
00462 
00463 NSS_IMPLEMENT PRStatus
00464 nssCryptokiPublicKey_GetAttributes (
00465   nssCryptokiObject *keyObject,
00466   nssSession *sessionOpt,
00467   NSSArena *arenaOpt,
00468   NSSKeyPairType *keyTypeOpt,
00469   NSSItem *idOpt
00470 )
00471 {
00472     PRStatus status;
00473     PRUint32 i;
00474     nssSession *session;
00475     NSSSlot *slot;
00476     CK_ULONG template_size;
00477     CK_ATTRIBUTE_PTR attr;
00478     CK_ATTRIBUTE key_template[2];
00479     /* Set up a template of all options chosen by caller */
00480     NSS_CK_TEMPLATE_START(key_template, attr, template_size);
00481     if (keyTypeOpt) {
00482        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_KEY_TYPE);
00483     }
00484     if (idOpt) {
00485        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
00486     }
00487     NSS_CK_TEMPLATE_FINISH(key_template, attr, template_size);
00488     if (template_size == 0) {
00489        /* caller didn't want anything */
00490        return PR_SUCCESS;
00491     }
00492 
00493     session = sessionOpt ? 
00494               sessionOpt : 
00495               nssToken_GetDefaultSession(keyObject->token);
00496 
00497     slot = nssToken_GetSlot(keyObject->token);
00498     status = nssCKObject_GetAttributes(keyObject->handle, 
00499                                        key_template, template_size,
00500                                        arenaOpt, session, slot);
00501     nssSlot_Destroy(slot);
00502     if (status != PR_SUCCESS) {
00503        return status;
00504     }
00505 
00506     i=0;
00507     if (keyTypeOpt) {
00508        *keyTypeOpt = nss_key_pair_type_from_ck_attrib(&key_template[i]); i++;
00509     }
00510     if (idOpt) {
00511        NSS_CK_ATTRIBUTE_TO_ITEM(&key_template[i], idOpt); i++;
00512     }
00513     return PR_SUCCESS;
00514 }
00515 #endif /* PURE_STAN_BUILD */
00516 
00517 static nssTrustLevel 
00518 get_nss_trust (
00519   CK_TRUST ckt
00520 )
00521 {
00522     nssTrustLevel t;
00523     switch (ckt) {
00524     case CKT_NETSCAPE_UNTRUSTED: t = nssTrustLevel_NotTrusted; break;
00525     case CKT_NETSCAPE_TRUSTED_DELEGATOR: t = nssTrustLevel_TrustedDelegator; 
00526        break;
00527     case CKT_NETSCAPE_VALID_DELEGATOR: t = nssTrustLevel_ValidDelegator; break;
00528     case CKT_NETSCAPE_TRUSTED: t = nssTrustLevel_Trusted; break;
00529     case CKT_NETSCAPE_VALID: t = nssTrustLevel_Valid; break;
00530     case CKT_NETSCAPE_MUST_VERIFY:
00531     case CKT_NETSCAPE_TRUST_UNKNOWN:
00532     default:
00533        t = nssTrustLevel_Unknown; break;
00534     }
00535     return t;
00536 }
00537 
00538 NSS_IMPLEMENT PRStatus
00539 nssCryptokiTrust_GetAttributes (
00540   nssCryptokiObject *trustObject,
00541   nssSession *sessionOpt,
00542   NSSItem *sha1_hash,
00543   nssTrustLevel *serverAuth,
00544   nssTrustLevel *clientAuth,
00545   nssTrustLevel *codeSigning,
00546   nssTrustLevel *emailProtection,
00547   PRBool *stepUpApproved
00548 )
00549 {
00550     PRStatus status;
00551     NSSSlot *slot;
00552     nssSession *session;
00553     CK_BBOOL isToken = PR_FALSE;
00554     CK_BBOOL stepUp = PR_FALSE;
00555     CK_TRUST saTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
00556     CK_TRUST caTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
00557     CK_TRUST epTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
00558     CK_TRUST csTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
00559     CK_ATTRIBUTE_PTR attr;
00560     CK_ATTRIBUTE trust_template[7];
00561     CK_ULONG trust_size;
00562 
00563     /* Use the trust object to find the trust settings */
00564     NSS_CK_TEMPLATE_START(trust_template, attr, trust_size);
00565     NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN,                  isToken);
00566     NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH,      saTrust);
00567     NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH,      caTrust);
00568     NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, epTrust);
00569     NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING,     csTrust);
00570     NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_STEP_UP_APPROVED, stepUp);
00571     NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH,     sha1_hash);
00572     NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size);
00573 
00574     status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL,
00575                                                 trustObject, 
00576                                                 CKO_NETSCAPE_TRUST,
00577                                                 trust_template, trust_size);
00578     if (status != PR_SUCCESS) {
00579        session = sessionOpt ? 
00580                  sessionOpt : 
00581                  nssToken_GetDefaultSession(trustObject->token);
00582 
00583        slot = nssToken_GetSlot(trustObject->token);
00584        status = nssCKObject_GetAttributes(trustObject->handle,
00585                                           trust_template, trust_size,
00586                                           NULL, session, slot);
00587        nssSlot_Destroy(slot);
00588        if (status != PR_SUCCESS) {
00589            return status;
00590        }
00591     }
00592 
00593     *serverAuth = get_nss_trust(saTrust);
00594     *clientAuth = get_nss_trust(caTrust);
00595     *emailProtection = get_nss_trust(epTrust);
00596     *codeSigning = get_nss_trust(csTrust);
00597     *stepUpApproved = stepUp;
00598     return PR_SUCCESS;
00599 }
00600 
00601 NSS_IMPLEMENT PRStatus
00602 nssCryptokiCRL_GetAttributes (
00603   nssCryptokiObject *crlObject,
00604   nssSession *sessionOpt,
00605   NSSArena *arenaOpt,
00606   NSSItem *encodingOpt,
00607   NSSItem *subjectOpt,
00608   CK_ULONG* crl_class,
00609   NSSUTF8 **urlOpt,
00610   PRBool *isKRLOpt
00611 )
00612 {
00613     PRStatus status;
00614     NSSSlot *slot;
00615     nssSession *session;
00616     CK_ATTRIBUTE_PTR attr;
00617     CK_ATTRIBUTE crl_template[7];
00618     CK_ULONG crl_size;
00619     PRUint32 i;
00620 
00621     NSS_CK_TEMPLATE_START(crl_template, attr, crl_size);
00622     if (crl_class) {
00623         NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CLASS);
00624     }
00625     if (encodingOpt) {
00626        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
00627     }
00628     if (urlOpt) {
00629        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_URL);
00630     }
00631     if (isKRLOpt) {
00632        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_KRL);
00633     }
00634     if (subjectOpt) {
00635        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT);
00636     }
00637     NSS_CK_TEMPLATE_FINISH(crl_template, attr, crl_size);
00638 
00639     status = nssToken_GetCachedObjectAttributes(crlObject->token, NULL,
00640                                                 crlObject, 
00641                                                 CKO_NETSCAPE_CRL,
00642                                                 crl_template, crl_size);
00643     if (status != PR_SUCCESS) {
00644        session = sessionOpt ? 
00645                  sessionOpt : 
00646                  nssToken_GetDefaultSession(crlObject->token);
00647 
00648        slot = nssToken_GetSlot(crlObject->token);
00649        status = nssCKObject_GetAttributes(crlObject->handle, 
00650                                           crl_template, crl_size,
00651                                           arenaOpt, session, slot);
00652        nssSlot_Destroy(slot);
00653        if (status != PR_SUCCESS) {
00654            return status;
00655        }
00656     }
00657 
00658     i=0;
00659     if (crl_class) {
00660         NSS_CK_ATTRIBUTE_TO_ULONG(&crl_template[i], *crl_class); i++;
00661     }
00662     if (encodingOpt) {
00663        NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], encodingOpt); i++;
00664     }
00665     if (urlOpt) {
00666        NSS_CK_ATTRIBUTE_TO_UTF8(&crl_template[i], *urlOpt); i++;
00667     }
00668     if (isKRLOpt) {
00669        NSS_CK_ATTRIBUTE_TO_BOOL(&crl_template[i], *isKRLOpt); i++;
00670     }
00671     if (subjectOpt) {
00672        NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], subjectOpt); i++;
00673     }
00674     return PR_SUCCESS;
00675 }
00676 
00677 NSS_IMPLEMENT PRStatus
00678 nssCryptokiPrivateKey_SetCertificate (
00679   nssCryptokiObject *keyObject,
00680   nssSession *sessionOpt,
00681   NSSUTF8 *nickname,
00682   NSSItem *id,
00683   NSSDER *subject
00684 )
00685 {
00686     CK_RV ckrv;
00687     CK_ATTRIBUTE_PTR attr;
00688     CK_ATTRIBUTE key_template[3];
00689     CK_ULONG key_size;
00690     void *epv = nssToken_GetCryptokiEPV(keyObject->token);
00691     nssSession *session;
00692     NSSToken *token = keyObject->token;
00693     nssSession *defaultSession = nssToken_GetDefaultSession(token);
00694     PRBool createdSession = PR_FALSE;
00695 
00696     NSS_CK_TEMPLATE_START(key_template, attr, key_size);
00697     NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
00698     NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
00699     NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
00700     NSS_CK_TEMPLATE_FINISH(key_template, attr, key_size);
00701 
00702     if (sessionOpt) {
00703        if (!nssSession_IsReadWrite(sessionOpt)) {
00704            return PR_FAILURE;
00705        } else {
00706            session = sessionOpt;
00707        }
00708     } else if (nssSession_IsReadWrite(defaultSession)) {
00709        session = defaultSession;
00710     } else {
00711        NSSSlot *slot = nssToken_GetSlot(token);
00712        session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE);
00713        createdSession = PR_TRUE;
00714        nssSlot_Destroy(slot);
00715     }
00716 
00717     ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle,
00718                                            keyObject->handle,
00719                                            key_template,
00720                                            key_size);
00721 
00722     if (createdSession) {
00723        nssSession_Destroy(session);
00724     }
00725 
00726     return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
00727 }
00728