andre@0: /* This Source Code Form is subject to the terms of the Mozilla Public andre@0: * License, v. 2.0. If a copy of the MPL was not distributed with this andre@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ andre@0: andre@0: #ifndef BUILTINS_H andre@0: #include "builtins.h" andre@0: #endif /* BUILTINS_H */ andre@0: andre@0: /* andre@0: * builtins/find.c andre@0: * andre@0: * This file implements the NSSCKMDFindObjects object for the andre@0: * "builtin objects" cryptoki module. andre@0: */ andre@0: andre@0: struct builtinsFOStr { andre@0: NSSArena *arena; andre@0: CK_ULONG n; andre@0: CK_ULONG i; andre@0: builtinsInternalObject **objs; andre@0: }; andre@0: andre@0: static void andre@0: builtins_mdFindObjects_Final andre@0: ( andre@0: NSSCKMDFindObjects *mdFindObjects, andre@0: NSSCKFWFindObjects *fwFindObjects, andre@0: NSSCKMDSession *mdSession, andre@0: NSSCKFWSession *fwSession, andre@0: NSSCKMDToken *mdToken, andre@0: NSSCKFWToken *fwToken, andre@0: NSSCKMDInstance *mdInstance, andre@0: NSSCKFWInstance *fwInstance andre@0: ) andre@0: { andre@0: struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc; andre@0: NSSArena *arena = fo->arena; andre@0: andre@0: nss_ZFreeIf(fo->objs); andre@0: nss_ZFreeIf(fo); andre@0: nss_ZFreeIf(mdFindObjects); andre@0: if ((NSSArena *)NULL != arena) { andre@0: NSSArena_Destroy(arena); andre@0: } andre@0: andre@0: return; andre@0: } andre@0: andre@0: static NSSCKMDObject * andre@0: builtins_mdFindObjects_Next andre@0: ( andre@0: NSSCKMDFindObjects *mdFindObjects, andre@0: NSSCKFWFindObjects *fwFindObjects, andre@0: NSSCKMDSession *mdSession, andre@0: NSSCKFWSession *fwSession, andre@0: NSSCKMDToken *mdToken, andre@0: NSSCKFWToken *fwToken, andre@0: NSSCKMDInstance *mdInstance, andre@0: NSSCKFWInstance *fwInstance, andre@0: NSSArena *arena, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc; andre@0: builtinsInternalObject *io; andre@0: andre@0: if( fo->i == fo->n ) { andre@0: *pError = CKR_OK; andre@0: return (NSSCKMDObject *)NULL; andre@0: } andre@0: andre@0: io = fo->objs[ fo->i ]; andre@0: fo->i++; andre@0: andre@0: return nss_builtins_CreateMDObject(arena, io, pError); andre@0: } andre@0: andre@0: static int andre@0: builtins_derUnwrapInt(unsigned char *src, int size, unsigned char **dest) { andre@0: unsigned char *start = src; andre@0: int len = 0; andre@0: andre@0: if (*src ++ != 2) { andre@0: return 0; andre@0: } andre@0: len = *src++; andre@0: if (len & 0x80) { andre@0: int count = len & 0x7f; andre@0: len =0; andre@0: andre@0: if (count+2 > size) { andre@0: return 0; andre@0: } andre@0: while (count-- > 0) { andre@0: len = (len << 8) | *src++; andre@0: } andre@0: } andre@0: if (len + (src-start) != size) { andre@0: return 0; andre@0: } andre@0: *dest = src; andre@0: return len; andre@0: } andre@0: andre@0: static CK_BBOOL andre@0: builtins_attrmatch andre@0: ( andre@0: CK_ATTRIBUTE_PTR a, andre@0: const NSSItem *b andre@0: ) andre@0: { andre@0: PRBool prb; andre@0: andre@0: if( a->ulValueLen != b->size ) { andre@0: /* match a decoded serial number */ andre@0: if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) { andre@0: int len; andre@0: unsigned char *data = NULL; andre@0: andre@0: len = builtins_derUnwrapInt(b->data,b->size,&data); andre@0: if (data && andre@0: (len == a->ulValueLen) && andre@0: nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) { andre@0: return CK_TRUE; andre@0: } andre@0: } andre@0: return CK_FALSE; andre@0: } andre@0: andre@0: prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL); andre@0: andre@0: if( PR_TRUE == prb ) { andre@0: return CK_TRUE; andre@0: } else { andre@0: return CK_FALSE; andre@0: } andre@0: } andre@0: andre@0: andre@0: static CK_BBOOL andre@0: builtins_match andre@0: ( andre@0: CK_ATTRIBUTE_PTR pTemplate, andre@0: CK_ULONG ulAttributeCount, andre@0: builtinsInternalObject *o andre@0: ) andre@0: { andre@0: CK_ULONG i; andre@0: andre@0: for( i = 0; i < ulAttributeCount; i++ ) { andre@0: CK_ULONG j; andre@0: andre@0: for( j = 0; j < o->n; j++ ) { andre@0: if( o->types[j] == pTemplate[i].type ) { andre@0: if( CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j]) ) { andre@0: return CK_FALSE; andre@0: } else { andre@0: break; andre@0: } andre@0: } andre@0: } andre@0: andre@0: if( j == o->n ) { andre@0: /* Loop ran to the end: no matching attribute */ andre@0: return CK_FALSE; andre@0: } andre@0: } andre@0: andre@0: /* Every attribute passed */ andre@0: return CK_TRUE; andre@0: } andre@0: andre@0: NSS_IMPLEMENT NSSCKMDFindObjects * andre@0: nss_builtins_FindObjectsInit andre@0: ( andre@0: NSSCKFWSession *fwSession, andre@0: CK_ATTRIBUTE_PTR pTemplate, andre@0: CK_ULONG ulAttributeCount, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: /* This could be made more efficient. I'm rather rushed. */ andre@0: NSSArena *arena; andre@0: NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL; andre@0: struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL; andre@0: builtinsInternalObject **temp = (builtinsInternalObject **)NULL; andre@0: PRUint32 i; andre@0: andre@0: arena = NSSArena_Create(); andre@0: if( (NSSArena *)NULL == arena ) { andre@0: goto loser; andre@0: } andre@0: andre@0: rv = nss_ZNEW(arena, NSSCKMDFindObjects); andre@0: if( (NSSCKMDFindObjects *)NULL == rv ) { andre@0: *pError = CKR_HOST_MEMORY; andre@0: goto loser; andre@0: } andre@0: andre@0: fo = nss_ZNEW(arena, struct builtinsFOStr); andre@0: if( (struct builtinsFOStr *)NULL == fo ) { andre@0: *pError = CKR_HOST_MEMORY; andre@0: goto loser; andre@0: } andre@0: andre@0: fo->arena = arena; andre@0: /* fo->n and fo->i are already zero */ andre@0: andre@0: rv->etc = (void *)fo; andre@0: rv->Final = builtins_mdFindObjects_Final; andre@0: rv->Next = builtins_mdFindObjects_Next; andre@0: rv->null = (void *)NULL; andre@0: andre@0: temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *, andre@0: nss_builtins_nObjects); andre@0: if( (builtinsInternalObject **)NULL == temp ) { andre@0: *pError = CKR_HOST_MEMORY; andre@0: goto loser; andre@0: } andre@0: andre@0: for( i = 0; i < nss_builtins_nObjects; i++ ) { andre@0: builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i]; andre@0: andre@0: if( CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o) ) { andre@0: temp[ fo->n ] = o; andre@0: fo->n++; andre@0: } andre@0: } andre@0: andre@0: fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n); andre@0: if( (builtinsInternalObject **)NULL == fo->objs ) { andre@0: *pError = CKR_HOST_MEMORY; andre@0: goto loser; andre@0: } andre@0: andre@0: (void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n); andre@0: nss_ZFreeIf(temp); andre@0: temp = (builtinsInternalObject **)NULL; andre@0: andre@0: return rv; andre@0: andre@0: loser: andre@0: nss_ZFreeIf(temp); andre@0: nss_ZFreeIf(fo); andre@0: nss_ZFreeIf(rv); andre@0: if ((NSSArena *)NULL != arena) { andre@0: NSSArena_Destroy(arena); andre@0: } andre@0: return (NSSCKMDFindObjects *)NULL; andre@0: } andre@0: