예제 #1
0
/* Creates a certificate from a base object */
NSS_IMPLEMENT NSSCertificate *
nssCertificate_Create (
  nssPKIObject *object
)
{
    PRStatus status;
    NSSCertificate *rvCert;
    nssArenaMark * mark;
    NSSArena *arena = object->arena;
    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
    PR_ASSERT(object->lockType == nssPKIMonitor);
    mark = nssArena_Mark(arena);
    rvCert = nss_ZNEW(arena, NSSCertificate);
    if (!rvCert) {
	return (NSSCertificate *)NULL;
    }
    rvCert->object = *object;
    /* XXX should choose instance based on some criteria */
    status = nssCryptokiCertificate_GetAttributes(object->instances[0],
                                                  NULL,  /* XXX sessionOpt */
                                                  arena,
                                                  &rvCert->type,
                                                  &rvCert->id,
                                                  &rvCert->encoding,
                                                  &rvCert->issuer,
                                                  &rvCert->serial,
                                                  &rvCert->subject);
    if (status != PR_SUCCESS ||
	!rvCert->encoding.data ||
	!rvCert->encoding.size ||
	!rvCert->issuer.data ||
	!rvCert->issuer.size ||
	!rvCert->serial.data ||
	!rvCert->serial.size) {
	if (mark)
	    nssArena_Release(arena, mark);
	return (NSSCertificate *)NULL;
    }
    if (mark)
	nssArena_Unmark(arena, mark);
    return rvCert;
}
예제 #2
0
파일: ckhelper.c 프로젝트: MekliCZ/positron
NSS_IMPLEMENT PRStatus
nssCKObject_GetAttributes(
    CK_OBJECT_HANDLE object,
    CK_ATTRIBUTE_PTR obj_template,
    CK_ULONG count,
    NSSArena *arenaOpt,
    nssSession *session,
    NSSSlot *slot)
{
    nssArenaMark *mark = NULL;
    CK_SESSION_HANDLE hSession;
    CK_ULONG i = 0;
    CK_RV ckrv;
    PRStatus nssrv;
    PRBool alloced = PR_FALSE;
    void *epv = nssSlot_GetCryptokiEPV(slot);
    hSession = session->handle;
    if (arenaOpt) {
        mark = nssArena_Mark(arenaOpt);
        if (!mark) {
            goto loser;
        }
    }
    nssSession_EnterMonitor(session);
    /* XXX kinda hacky, if the storage size is already in the first template
     * item, then skip the alloc portion
     */
    if (obj_template[0].ulValueLen == 0) {
        /* Get the storage size needed for each attribute */
        ckrv = CKAPI(epv)->C_GetAttributeValue(hSession,
                                               object, obj_template, count);
        if (ckrv != CKR_OK &&
            ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
            ckrv != CKR_ATTRIBUTE_SENSITIVE) {
            nssSession_ExitMonitor(session);
            nss_SetError(NSS_ERROR_DEVICE_ERROR);
            goto loser;
        }
        /* Allocate memory for each attribute. */
        for (i = 0; i < count; i++) {
            CK_ULONG ulValueLen = obj_template[i].ulValueLen;
            if (ulValueLen == 0 || ulValueLen == (CK_ULONG)-1) {
                obj_template[i].pValue = NULL;
                obj_template[i].ulValueLen = 0;
                continue;
            }
            if (is_string_attribute(obj_template[i].type)) {
                ulValueLen++;
            }
            obj_template[i].pValue = nss_ZAlloc(arenaOpt, ulValueLen);
            if (!obj_template[i].pValue) {
                nssSession_ExitMonitor(session);
                goto loser;
            }
        }
        alloced = PR_TRUE;
    }
    /* Obtain the actual attribute values. */
    ckrv = CKAPI(epv)->C_GetAttributeValue(hSession,
                                           object, obj_template, count);
    nssSession_ExitMonitor(session);
    if (ckrv != CKR_OK &&
        ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
        ckrv != CKR_ATTRIBUTE_SENSITIVE) {
        nss_SetError(NSS_ERROR_DEVICE_ERROR);
        goto loser;
    }
    if (alloced && arenaOpt) {
        nssrv = nssArena_Unmark(arenaOpt, mark);
        if (nssrv != PR_SUCCESS) {
            goto loser;
        }
    }

    if (count > 1 && ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) ||
                      (ckrv == CKR_ATTRIBUTE_SENSITIVE))) {
        /* old tokens would keep the length of '0' and not deal with any
         * of the attributes we passed. For those tokens read them one at
         * a time */
        for (i = 0; i < count; i++) {
            if ((obj_template[i].ulValueLen == 0) ||
                (obj_template[i].ulValueLen == -1)) {
                obj_template[i].ulValueLen = 0;
                (void)nssCKObject_GetAttributes(object, &obj_template[i], 1,
                                                arenaOpt, session, slot);
            }
        }
    }
    return PR_SUCCESS;
loser:
    if (alloced) {
        if (arenaOpt) {
            /* release all arena memory allocated before the failure. */
            (void)nssArena_Release(arenaOpt, mark);
        } else {
            CK_ULONG j;
            /* free each heap object that was allocated before the failure. */
            for (j = 0; j < i; j++) {
                nss_ZFreeIf(obj_template[j].pValue);
            }
        }
    }
    return PR_FAILURE;
}