mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-14 11:40:13 +01:00
98d377b37b
bug920719, bug1026148, bug1028647, bug963150, bug1030486, bug1025729, bug836658, bug1028582, bug1038728, bug1038526, bug1042634, bug1047210, bug1043891, bug1043108, bug1046735, bug1043082, bug1036735, bug1046718, bug1050107, bug1054625, bug1057465, bug1057476, bug1041326, bug1058933, bug1064636, bug1057161, bug1078669, bug1049435, bug1070493, bug1083360, bug1028764, bug1065990, bug1073330, bug1064670, bug1094650
272 lines
6.0 KiB
C
272 lines
6.0 KiB
C
/* 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/. */
|
|
|
|
#ifndef BUILTINS_H
|
|
#include "builtins.h"
|
|
#endif /* BUILTINS_H */
|
|
|
|
/*
|
|
* builtins/find.c
|
|
*
|
|
* This file implements the NSSCKMDFindObjects object for the
|
|
* "builtin objects" cryptoki module.
|
|
*/
|
|
|
|
struct builtinsFOStr {
|
|
NSSArena *arena;
|
|
CK_ULONG n;
|
|
CK_ULONG i;
|
|
builtinsInternalObject **objs;
|
|
};
|
|
|
|
static void
|
|
builtins_mdFindObjects_Final
|
|
(
|
|
NSSCKMDFindObjects *mdFindObjects,
|
|
NSSCKFWFindObjects *fwFindObjects,
|
|
NSSCKMDSession *mdSession,
|
|
NSSCKFWSession *fwSession,
|
|
NSSCKMDToken *mdToken,
|
|
NSSCKFWToken *fwToken,
|
|
NSSCKMDInstance *mdInstance,
|
|
NSSCKFWInstance *fwInstance
|
|
)
|
|
{
|
|
struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
|
|
NSSArena *arena = fo->arena;
|
|
|
|
nss_ZFreeIf(fo->objs);
|
|
nss_ZFreeIf(fo);
|
|
nss_ZFreeIf(mdFindObjects);
|
|
if ((NSSArena *)NULL != arena) {
|
|
NSSArena_Destroy(arena);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static NSSCKMDObject *
|
|
builtins_mdFindObjects_Next
|
|
(
|
|
NSSCKMDFindObjects *mdFindObjects,
|
|
NSSCKFWFindObjects *fwFindObjects,
|
|
NSSCKMDSession *mdSession,
|
|
NSSCKFWSession *fwSession,
|
|
NSSCKMDToken *mdToken,
|
|
NSSCKFWToken *fwToken,
|
|
NSSCKMDInstance *mdInstance,
|
|
NSSCKFWInstance *fwInstance,
|
|
NSSArena *arena,
|
|
CK_RV *pError
|
|
)
|
|
{
|
|
struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
|
|
builtinsInternalObject *io;
|
|
|
|
if( fo->i == fo->n ) {
|
|
*pError = CKR_OK;
|
|
return (NSSCKMDObject *)NULL;
|
|
}
|
|
|
|
io = fo->objs[ fo->i ];
|
|
fo->i++;
|
|
|
|
return nss_builtins_CreateMDObject(arena, io, pError);
|
|
}
|
|
|
|
static int
|
|
builtins_derUnwrapInt(unsigned char *src, int size, unsigned char **dest) {
|
|
unsigned char *start = src;
|
|
int len = 0;
|
|
|
|
if (*src ++ != 2) {
|
|
return 0;
|
|
}
|
|
len = *src++;
|
|
if (len & 0x80) {
|
|
int count = len & 0x7f;
|
|
len =0;
|
|
|
|
if (count+2 > size) {
|
|
return 0;
|
|
}
|
|
while (count-- > 0) {
|
|
len = (len << 8) | *src++;
|
|
}
|
|
}
|
|
if (len + (src-start) != size) {
|
|
return 0;
|
|
}
|
|
*dest = src;
|
|
return len;
|
|
}
|
|
|
|
static CK_BBOOL
|
|
builtins_attrmatch
|
|
(
|
|
CK_ATTRIBUTE_PTR a,
|
|
const NSSItem *b
|
|
)
|
|
{
|
|
PRBool prb;
|
|
|
|
if( a->ulValueLen != b->size ) {
|
|
/* match a decoded serial number */
|
|
if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
|
|
int len;
|
|
unsigned char *data = NULL;
|
|
|
|
len = builtins_derUnwrapInt(b->data,b->size,&data);
|
|
if (data &&
|
|
(len == a->ulValueLen) &&
|
|
nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
|
|
return CK_TRUE;
|
|
}
|
|
}
|
|
return CK_FALSE;
|
|
}
|
|
|
|
prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
|
|
|
|
if( PR_TRUE == prb ) {
|
|
return CK_TRUE;
|
|
} else {
|
|
return CK_FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
static CK_BBOOL
|
|
builtins_match
|
|
(
|
|
CK_ATTRIBUTE_PTR pTemplate,
|
|
CK_ULONG ulAttributeCount,
|
|
builtinsInternalObject *o
|
|
)
|
|
{
|
|
CK_ULONG i;
|
|
|
|
for( i = 0; i < ulAttributeCount; i++ ) {
|
|
CK_ULONG j;
|
|
|
|
for( j = 0; j < o->n; j++ ) {
|
|
if( o->types[j] == pTemplate[i].type ) {
|
|
if( CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j]) ) {
|
|
return CK_FALSE;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( j == o->n ) {
|
|
/* Loop ran to the end: no matching attribute */
|
|
return CK_FALSE;
|
|
}
|
|
}
|
|
|
|
/* Every attribute passed */
|
|
return CK_TRUE;
|
|
}
|
|
|
|
NSS_IMPLEMENT NSSCKMDFindObjects *
|
|
nss_builtins_FindObjectsInit
|
|
(
|
|
NSSCKFWSession *fwSession,
|
|
CK_ATTRIBUTE_PTR pTemplate,
|
|
CK_ULONG ulAttributeCount,
|
|
CK_RV *pError
|
|
)
|
|
{
|
|
/* This could be made more efficient. I'm rather rushed. */
|
|
NSSArena *arena;
|
|
NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
|
|
struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL;
|
|
|
|
/*
|
|
* 99% of the time we get 0 or 1 matches. So we start with a small
|
|
* stack-allocated array to hold the matches and switch to a heap-allocated
|
|
* array later if the number of matches exceeds STACK_BUF_LENGTH.
|
|
*/
|
|
#define STACK_BUF_LENGTH 1
|
|
builtinsInternalObject *stackTemp[STACK_BUF_LENGTH];
|
|
builtinsInternalObject **temp = stackTemp;
|
|
PRBool tempIsHeapAllocated = PR_FALSE;
|
|
PRUint32 i;
|
|
|
|
arena = NSSArena_Create();
|
|
if( (NSSArena *)NULL == arena ) {
|
|
goto loser;
|
|
}
|
|
|
|
rv = nss_ZNEW(arena, NSSCKMDFindObjects);
|
|
if( (NSSCKMDFindObjects *)NULL == rv ) {
|
|
*pError = CKR_HOST_MEMORY;
|
|
goto loser;
|
|
}
|
|
|
|
fo = nss_ZNEW(arena, struct builtinsFOStr);
|
|
if( (struct builtinsFOStr *)NULL == fo ) {
|
|
*pError = CKR_HOST_MEMORY;
|
|
goto loser;
|
|
}
|
|
|
|
fo->arena = arena;
|
|
/* fo->n and fo->i are already zero */
|
|
|
|
rv->etc = (void *)fo;
|
|
rv->Final = builtins_mdFindObjects_Final;
|
|
rv->Next = builtins_mdFindObjects_Next;
|
|
rv->null = (void *)NULL;
|
|
|
|
for( i = 0; i < nss_builtins_nObjects; i++ ) {
|
|
builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i];
|
|
|
|
if( CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o) ) {
|
|
if( fo->n == STACK_BUF_LENGTH ) {
|
|
/* Switch from the small stack array to a heap-allocated array large
|
|
* enough to handle matches in all remaining cases. */
|
|
temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
|
|
fo->n + nss_builtins_nObjects - i);
|
|
if( (builtinsInternalObject **)NULL == temp ) {
|
|
*pError = CKR_HOST_MEMORY;
|
|
goto loser;
|
|
}
|
|
tempIsHeapAllocated = PR_TRUE;
|
|
(void)nsslibc_memcpy(temp, stackTemp,
|
|
sizeof(builtinsInternalObject *) * fo->n);
|
|
}
|
|
|
|
temp[ fo->n ] = o;
|
|
fo->n++;
|
|
}
|
|
}
|
|
|
|
fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n);
|
|
if( (builtinsInternalObject **)NULL == fo->objs ) {
|
|
*pError = CKR_HOST_MEMORY;
|
|
goto loser;
|
|
}
|
|
|
|
(void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n);
|
|
if (tempIsHeapAllocated) {
|
|
nss_ZFreeIf(temp);
|
|
temp = (builtinsInternalObject **)NULL;
|
|
}
|
|
|
|
return rv;
|
|
|
|
loser:
|
|
if (tempIsHeapAllocated) {
|
|
nss_ZFreeIf(temp);
|
|
}
|
|
nss_ZFreeIf(fo);
|
|
nss_ZFreeIf(rv);
|
|
if ((NSSArena *)NULL != arena) {
|
|
NSSArena_Destroy(arena);
|
|
}
|
|
return (NSSCKMDFindObjects *)NULL;
|
|
}
|
|
|