Back to index

lightning-sunbird  0.9+nobinonly
Functions
pk11kea.c File Reference
#include "seccomon.h"
#include "secmod.h"
#include "nssilock.h"
#include "secmodi.h"
#include "secmodti.h"
#include "pkcs11.h"
#include "pk11func.h"
#include "secitem.h"
#include "key.h"
#include "secasn1.h"
#include "sechash.h"
#include "cert.h"
#include "secerr.h"

Go to the source code of this file.

Functions

static CK_OBJECT_HANDLE pk11_FindRSAPubKey (PK11SlotInfo *slot)
PK11SymKey * pk11_KeyExchange (PK11SlotInfo *slot, CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags, PRBool isPerm, PK11SymKey *symKey)

Function Documentation

static CK_OBJECT_HANDLE pk11_FindRSAPubKey ( PK11SlotInfo *  slot) [static]

Definition at line 59 of file pk11kea.c.

{
    CK_KEY_TYPE key_type = CKK_RSA;
    CK_OBJECT_CLASS class_type = CKO_PUBLIC_KEY;
    CK_ATTRIBUTE theTemplate[2];
    int template_count = sizeof(theTemplate)/sizeof(theTemplate[0]);
    CK_ATTRIBUTE *attrs = theTemplate;

    PK11_SETATTRS(attrs,CKA_CLASS,&class_type,sizeof(class_type)); attrs++;
    PK11_SETATTRS(attrs,CKA_KEY_TYPE,&key_type,sizeof(key_type)); attrs++;
    template_count = attrs - theTemplate;
    PR_ASSERT(template_count <= sizeof(theTemplate)/sizeof(CK_ATTRIBUTE));

    return pk11_FindObjectByTemplate(slot,theTemplate,template_count);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PK11SymKey* pk11_KeyExchange ( PK11SlotInfo *  slot,
CK_MECHANISM_TYPE  type,
CK_ATTRIBUTE_TYPE  operation,
CK_FLAGS  flags,
PRBool  isPerm,
PK11SymKey *  symKey 
)

Definition at line 76 of file pk11kea.c.

{
    PK11SymKey *newSymKey = NULL;
    SECStatus rv;
    /* performance improvement can go here --- use a generated key at startup
     * to generate a per token wrapping key. If it exists, use it, otherwise 
     * do a full key exchange. */

    /* find a common Key Exchange algorithm */
    /* RSA */
    if (PK11_DoesMechanism(symKey->slot, CKM_RSA_PKCS) && 
                            PK11_DoesMechanism(slot,CKM_RSA_PKCS)) {
       CK_OBJECT_HANDLE pubKeyHandle = CK_INVALID_HANDLE;
       CK_OBJECT_HANDLE privKeyHandle = CK_INVALID_HANDLE;
       SECKEYPublicKey *pubKey = NULL;
       SECKEYPrivateKey *privKey = NULL;
       SECItem wrapData;
       unsigned int     symKeyLength = PK11_GetKeyLength(symKey);

       wrapData.data = NULL;

       /* find RSA Public Key on target */
       pubKeyHandle = pk11_FindRSAPubKey(slot);
       if (pubKeyHandle != CK_INVALID_HANDLE) {
           privKeyHandle = PK11_MatchItem(slot,pubKeyHandle,CKO_PRIVATE_KEY);
       }

       /* if no key exists, generate a key pair */
       if (privKeyHandle == CK_INVALID_HANDLE) {
           PK11RSAGenParams rsaParams;

           if (symKeyLength > 53) /* bytes */ {
              /* we'd have to generate an RSA key pair > 512 bits long,
              ** and that's too costly.  Don't even try. 
              */
              PORT_SetError( SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY );
              goto rsa_failed;
           }
           rsaParams.keySizeInBits = 
               (symKeyLength > 21 || symKeyLength == 0) ? 512 : 256;
           rsaParams.pe  = 0x10001;
           privKey = PK11_GenerateKeyPair(slot,CKM_RSA_PKCS_KEY_PAIR_GEN, 
                         &rsaParams, &pubKey,PR_FALSE,PR_TRUE,symKey->cx);
       } else {
           /* if keys exist, build SECKEY data structures for them */
           privKey = PK11_MakePrivKey(slot,nullKey, PR_TRUE, privKeyHandle,
                                   symKey->cx);
           if (privKey != NULL) {
              pubKey = PK11_ExtractPublicKey(slot, rsaKey, pubKeyHandle);
              if (pubKey && pubKey->pkcs11Slot) {
                  PK11_FreeSlot(pubKey->pkcs11Slot);
                  pubKey->pkcs11Slot = NULL;
                  pubKey->pkcs11ID = CK_INVALID_HANDLE;
              }
           }
       }
       if (privKey == NULL) goto rsa_failed;
       if (pubKey == NULL)  goto rsa_failed;

        wrapData.len  = SECKEY_PublicKeyStrength(pubKey);
        if (!wrapData.len) goto rsa_failed;
        wrapData.data = PORT_Alloc(wrapData.len);
        if (wrapData.data == NULL) goto rsa_failed;

       /* now wrap the keys in and out */
       rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, pubKey, symKey, &wrapData);
       if (rv == SECSuccess) {
           newSymKey = PK11_PubUnwrapSymKeyWithFlagsPerm(privKey,
                     &wrapData,type,operation,symKeyLength,flags,isPerm);
       }
rsa_failed:
       if (wrapData.data != NULL) PORT_Free(wrapData.data);
       if (privKey != NULL) SECKEY_DestroyPrivateKey(privKey);
       if (pubKey != NULL) SECKEY_DestroyPublicKey(pubKey);

       return  newSymKey;
    }
    PORT_SetError( SEC_ERROR_NO_MODULE );
    return NULL;
}

Here is the call graph for this function: