security/nss/lib/ckfw/nssmkey/mfind.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #ifndef CKMK_H
     6 #include "ckmk.h"
     7 #endif /* CKMK_H */
     9 /*
    10  * nssmkey/mfind.c
    11  *
    12  * This file implements the NSSCKMDFindObjects object for the
    13  * "nssmkey" cryptoki module.
    14  */
    16 struct ckmkFOStr {
    17   NSSArena *arena;
    18   CK_ULONG n;
    19   CK_ULONG i;
    20   ckmkInternalObject **objs;
    21 };
    23 static void
    24 ckmk_mdFindObjects_Final
    25 (
    26   NSSCKMDFindObjects *mdFindObjects,
    27   NSSCKFWFindObjects *fwFindObjects,
    28   NSSCKMDSession *mdSession,
    29   NSSCKFWSession *fwSession,
    30   NSSCKMDToken *mdToken,
    31   NSSCKFWToken *fwToken,
    32   NSSCKMDInstance *mdInstance,
    33   NSSCKFWInstance *fwInstance
    34 )
    35 {
    36   struct ckmkFOStr *fo = (struct ckmkFOStr *)mdFindObjects->etc;
    37   NSSArena *arena = fo->arena;
    38   PRUint32 i;
    40   /* walk down an free the unused 'objs' */
    41   for (i=fo->i; i < fo->n ; i++) {
    42     nss_ckmk_DestroyInternalObject(fo->objs[i]);
    43   }
    45   nss_ZFreeIf(fo->objs);
    46   nss_ZFreeIf(fo);
    47   nss_ZFreeIf(mdFindObjects);
    48   if ((NSSArena *)NULL != arena) {
    49     NSSArena_Destroy(arena);
    50   }
    52   return;
    53 }
    55 static NSSCKMDObject *
    56 ckmk_mdFindObjects_Next
    57 (
    58   NSSCKMDFindObjects *mdFindObjects,
    59   NSSCKFWFindObjects *fwFindObjects,
    60   NSSCKMDSession *mdSession,
    61   NSSCKFWSession *fwSession,
    62   NSSCKMDToken *mdToken,
    63   NSSCKFWToken *fwToken,
    64   NSSCKMDInstance *mdInstance,
    65   NSSCKFWInstance *fwInstance,
    66   NSSArena *arena,
    67   CK_RV *pError
    68 )
    69 {
    70   struct ckmkFOStr *fo = (struct ckmkFOStr *)mdFindObjects->etc;
    71   ckmkInternalObject *io;
    73   if( fo->i == fo->n ) {
    74     *pError = CKR_OK;
    75     return (NSSCKMDObject *)NULL;
    76   }
    78   io = fo->objs[ fo->i ];
    79   fo->i++;
    81   return nss_ckmk_CreateMDObject(arena, io, pError);
    82 }
    84 static CK_BBOOL
    85 ckmk_attrmatch
    86 (
    87   CK_ATTRIBUTE_PTR a,
    88   ckmkInternalObject *o
    89 )
    90 {
    91   PRBool prb;
    92   const NSSItem *b;
    93   CK_RV error;
    95   b = nss_ckmk_FetchAttribute(o, a->type,  &error);
    96   if (b == NULL) {
    97     return CK_FALSE;
    98   }
   100   if( a->ulValueLen != b->size ) {
   101     /* match a decoded serial number */
   102     if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
   103 	int len;
   104 	unsigned char *data;
   106 	data = nss_ckmk_DERUnwrap(b->data, b->size, &len, NULL);
   107 	if ((len == a->ulValueLen) && 
   108 		nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
   109 	    return CK_TRUE;
   110 	}
   111     }
   112     return CK_FALSE;
   113   }
   115   prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
   117   if( PR_TRUE == prb ) {
   118     return CK_TRUE;
   119   } else {
   120     return CK_FALSE;
   121   }
   122 }
   125 static CK_BBOOL
   126 ckmk_match
   127 (
   128   CK_ATTRIBUTE_PTR pTemplate,
   129   CK_ULONG ulAttributeCount,
   130   ckmkInternalObject *o
   131 )
   132 {
   133   CK_ULONG i;
   135   for( i = 0; i < ulAttributeCount; i++ ) {
   136     if (CK_FALSE == ckmk_attrmatch(&pTemplate[i], o)) {
   137       return CK_FALSE;
   138     }
   139   }
   141   /* Every attribute passed */
   142   return CK_TRUE;
   143 }
   145 #define CKMK_ITEM_CHUNK  20
   147 #define PUT_OBJECT(obj, err, size, count, list) \
   148   { \
   149     if (count >= size) { \
   150     (list) = (list) ? \
   151 		nss_ZREALLOCARRAY(list, ckmkInternalObject *, \
   152 		               ((size)+CKMK_ITEM_CHUNK) ) : \
   153 		nss_ZNEWARRAY(NULL, ckmkInternalObject *, \
   154 		               ((size)+CKMK_ITEM_CHUNK) ) ; \
   155       if ((ckmkInternalObject **)NULL == list) { \
   156         err = CKR_HOST_MEMORY; \
   157         goto loser; \
   158       } \
   159       (size) += CKMK_ITEM_CHUNK; \
   160     } \
   161     (list)[ count ] = (obj); \
   162     count++; \
   163   }
   166 /* find all the certs that represent the appropriate object (cert, priv key, or
   167  *  pub key) in the cert store.
   168  */
   169 static PRUint32
   170 collect_class(
   171   CK_OBJECT_CLASS objClass,
   172   SecItemClass itemClass,
   173   CK_ATTRIBUTE_PTR pTemplate, 
   174   CK_ULONG ulAttributeCount, 
   175   ckmkInternalObject ***listp,
   176   PRUint32 *sizep,
   177   PRUint32 count,
   178   CK_RV *pError
   179 )
   180 {
   181   ckmkInternalObject *next = NULL;
   182   SecKeychainSearchRef searchRef = 0;
   183   SecKeychainItemRef itemRef = 0;
   184   OSStatus error;
   186   /* future, build the attribute list based on the template
   187    * so we can refine the search */
   188   error = SecKeychainSearchCreateFromAttributes( 
   189 		NULL, itemClass, NULL, &searchRef);
   191   while (noErr == SecKeychainSearchCopyNext(searchRef, &itemRef)) {
   192     /* if we don't have an internal object structure, get one */
   193     if ((ckmkInternalObject *)NULL == next) {
   194       next = nss_ZNEW(NULL, ckmkInternalObject);
   195       if ((ckmkInternalObject *)NULL == next) {
   196         *pError = CKR_HOST_MEMORY;
   197         goto loser;
   198       }
   199     }
   200     /* fill in the relevant object data */
   201     next->type = ckmkItem;
   202     next->objClass = objClass;
   203     next->u.item.itemRef = itemRef;
   204     next->u.item.itemClass = itemClass;
   206     /* see if this is one of the objects we are looking for */
   207     if( CK_TRUE == ckmk_match(pTemplate, ulAttributeCount, next) ) {
   208       /* yes, put it on the list */
   209       PUT_OBJECT(next, *pError, *sizep, count, *listp);
   210       next = NULL; /* this one is on the list, need to allocate a new one now */
   211     } else {
   212       /* no , release the current item and clear out the structure for reuse */
   213       CFRelease(itemRef);
   214       /* don't cache the values we just loaded */
   215       nsslibc_memset(next, 0, sizeof(*next));
   216     }
   217   }
   218 loser:
   219   if (searchRef) {
   220     CFRelease(searchRef);
   221   }
   222   nss_ZFreeIf(next);
   223   return count;
   224 }
   226 static PRUint32
   227 collect_objects(
   228   CK_ATTRIBUTE_PTR pTemplate, 
   229   CK_ULONG ulAttributeCount, 
   230   ckmkInternalObject ***listp,
   231   CK_RV *pError
   232 )
   233 {
   234   PRUint32 i;
   235   PRUint32 count = 0;
   236   PRUint32 size = 0;
   237   CK_OBJECT_CLASS objClass;
   239   /*
   240    * first handle the static build in objects (if any)
   241    */
   242   for( i = 0; i < nss_ckmk_nObjects; i++ ) {
   243     ckmkInternalObject *o = (ckmkInternalObject *)&nss_ckmk_data[i];
   245     if( CK_TRUE == ckmk_match(pTemplate, ulAttributeCount, o) ) {
   246       PUT_OBJECT(o, *pError, size, count, *listp);
   247     }
   248   }
   250   /*
   251    * now handle the various object types
   252    */
   253   objClass = nss_ckmk_GetULongAttribute(CKA_CLASS, 
   254 		pTemplate, ulAttributeCount, pError);
   255   if (CKR_OK != *pError) {
   256     objClass = CK_INVALID_HANDLE;
   257   }
   258   *pError = CKR_OK;
   259   switch (objClass) {
   260   case CKO_CERTIFICATE:
   261     count = collect_class(objClass, kSecCertificateItemClass,
   262                               pTemplate, ulAttributeCount, listp, 
   263                               &size, count, pError);
   264     break;
   265   case CKO_PUBLIC_KEY:
   266     count = collect_class(objClass,  CSSM_DL_DB_RECORD_PUBLIC_KEY,
   267                               pTemplate, ulAttributeCount, listp, 
   268                               &size, count, pError);
   269     break;
   270   case CKO_PRIVATE_KEY:
   271     count = collect_class(objClass,  CSSM_DL_DB_RECORD_PRIVATE_KEY,
   272                               pTemplate, ulAttributeCount, listp, 
   273                               &size, count, pError);
   274     break;
   275   /* all of them */
   276   case CK_INVALID_HANDLE:
   277     count = collect_class(CKO_CERTIFICATE, kSecCertificateItemClass,
   278                               pTemplate, ulAttributeCount, listp, 
   279                               &size, count, pError);
   280     count = collect_class(CKO_PUBLIC_KEY,  CSSM_DL_DB_RECORD_PUBLIC_KEY,
   281                               pTemplate, ulAttributeCount, listp, 
   282                               &size, count, pError);
   283     count = collect_class(CKO_PUBLIC_KEY,  CSSM_DL_DB_RECORD_PRIVATE_KEY,
   284                               pTemplate, ulAttributeCount, listp, 
   285                               &size, count, pError);
   286     break;
   287   default:
   288     break;
   289   }
   290   if (CKR_OK != *pError) {
   291     goto loser;
   292   }
   294   return count;
   295 loser:
   296   nss_ZFreeIf(*listp);
   297   return 0;
   298 }
   301 NSS_IMPLEMENT NSSCKMDFindObjects *
   302 nss_ckmk_FindObjectsInit
   303 (
   304   NSSCKFWSession *fwSession,
   305   CK_ATTRIBUTE_PTR pTemplate,
   306   CK_ULONG ulAttributeCount,
   307   CK_RV *pError
   308 )
   309 {
   310   /* This could be made more efficient.  I'm rather rushed. */
   311   NSSArena *arena;
   312   NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
   313   struct ckmkFOStr *fo = (struct ckmkFOStr *)NULL;
   314   ckmkInternalObject **temp = (ckmkInternalObject **)NULL;
   316   arena = NSSArena_Create();
   317   if( (NSSArena *)NULL == arena ) {
   318     goto loser;
   319   }
   321   rv = nss_ZNEW(arena, NSSCKMDFindObjects);
   322   if( (NSSCKMDFindObjects *)NULL == rv ) {
   323     *pError = CKR_HOST_MEMORY;
   324     goto loser;
   325   }
   327   fo = nss_ZNEW(arena, struct ckmkFOStr);
   328   if( (struct ckmkFOStr *)NULL == fo ) {
   329     *pError = CKR_HOST_MEMORY;
   330     goto loser;
   331   }
   333   fo->arena = arena;
   334   /* fo->n and fo->i are already zero */
   336   rv->etc = (void *)fo;
   337   rv->Final = ckmk_mdFindObjects_Final;
   338   rv->Next = ckmk_mdFindObjects_Next;
   339   rv->null = (void *)NULL;
   341   fo->n = collect_objects(pTemplate, ulAttributeCount, &temp, pError);
   342   if (*pError != CKR_OK) {
   343     goto loser;
   344   }
   346   fo->objs = nss_ZNEWARRAY(arena, ckmkInternalObject *, fo->n);
   347   if( (ckmkInternalObject **)NULL == fo->objs ) {
   348     *pError = CKR_HOST_MEMORY;
   349     goto loser;
   350   }
   352   (void)nsslibc_memcpy(fo->objs, temp, sizeof(ckmkInternalObject *) * fo->n);
   353   nss_ZFreeIf(temp);
   354   temp = (ckmkInternalObject **)NULL;
   356   return rv;
   358  loser:
   359   nss_ZFreeIf(temp);
   360   nss_ZFreeIf(fo);
   361   nss_ZFreeIf(rv);
   362   if ((NSSArena *)NULL != arena) {
   363      NSSArena_Destroy(arena);
   364   }
   365   return (NSSCKMDFindObjects *)NULL;
   366 }

mercurial