Skip to content

Commit

Permalink
Bug 453364: mapped the NSS error codes that may be set by freebl func…
Browse files Browse the repository at this point in the history
…tions

to the PKCS #11 CK_RV error codes.  r=rrelyea.
  • Loading branch information
wtc%google.com committed Nov 18, 2008
1 parent e6eed41 commit 41f42d5
Showing 1 changed file with 92 additions and 45 deletions.
137 changes: 92 additions & 45 deletions security/nss/lib/softoken/pkcs11c.c
Expand Up @@ -127,6 +127,69 @@ sftk_Space(void *data, PRBool freeit)
PORT_Free(data);
}

/*
* map all the SEC_ERROR_xxx error codes that may be returned by freebl
* functions to CKR_xxx. return CKR_DEVICE_ERROR by default for backward
* compatibility.
*/
static CK_RV
sftk_MapCryptError(int error)
{
switch (error) {
case SEC_ERROR_INVALID_ARGS:
case SEC_ERROR_BAD_DATA: /* MP_RANGE gets mapped to this */
return CKR_ARGUMENTS_BAD;
case SEC_ERROR_INPUT_LEN:
return CKR_DATA_LEN_RANGE;
case SEC_ERROR_OUTPUT_LEN:
return CKR_BUFFER_TOO_SMALL;
case SEC_ERROR_LIBRARY_FAILURE:
return CKR_GENERAL_ERROR;
case SEC_ERROR_NO_MEMORY:
return CKR_HOST_MEMORY;
case SEC_ERROR_BAD_SIGNATURE:
return CKR_SIGNATURE_INVALID;
case SEC_ERROR_INVALID_KEY:
return CKR_KEY_SIZE_RANGE;
case SEC_ERROR_BAD_KEY: /* an EC public key that fails validation */
return CKR_KEY_SIZE_RANGE; /* the closest error code */
case SEC_ERROR_UNSUPPORTED_EC_POINT_FORM:
return CKR_TEMPLATE_INCONSISTENT;
/* EC functions set this error if NSS_ENABLE_ECC is not defined */
case SEC_ERROR_UNSUPPORTED_KEYALG:
return CKR_MECHANISM_INVALID;
/* key pair generation failed after max number of attempts */
case SEC_ERROR_NEED_RANDOM:
return CKR_FUNCTION_FAILED;
}
return CKR_DEVICE_ERROR;
}

/* used by Decrypt and UnwrapKey (indirectly) */
static CK_RV
sftk_MapDecryptError(int error)
{
switch (error) {
case SEC_ERROR_BAD_DATA:
return CKR_ENCRYPTED_DATA_INVALID;
default:
return sftk_MapCryptError(error);
}
}

/*
* return CKR_SIGNATURE_INVALID instead of CKR_DEVICE_ERROR by default for
* backward compatibilty.
*/
static CK_RV
sftk_MapVerifyError(int error)
{
CK_RV crv = sftk_MapCryptError(error);
if (crv == CKR_DEVICE_ERROR)
crv = CKR_SIGNATURE_INVALID;
return crv;
}


/*
* turn a CDMF key into a des key. CDMF is an old IBM scheme to export DES by
Expand Down Expand Up @@ -154,7 +217,7 @@ sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey)
if (descx == NULL) return CKR_HOST_MEMORY;
rv = DES_Encrypt(descx, enc_dest, &leng, 8, enc_src, 8);
DES_DestroyContext(descx,PR_TRUE);
if (rv != SECSuccess) return CKR_DEVICE_ERROR;
if (rv != SECSuccess) return sftk_MapCryptError(PORT_GetError());

/* xor source with des, zero the parity bits and deprecate the key*/
for (i=0; i < 8; i++) {
Expand All @@ -170,7 +233,7 @@ sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey)
if (descx == NULL) return CKR_HOST_MEMORY;
rv = DES_Encrypt(descx, deskey, &leng, 8, enc_src, 8);
DES_DestroyContext(descx,PR_TRUE);
if (rv != SECSuccess) return CKR_DEVICE_ERROR;
if (rv != SECSuccess) return sftk_MapCryptError(PORT_GetError());

/* set the corret parity on our new des key */
sftk_FormatDESKey(deskey, 8);
Expand Down Expand Up @@ -246,23 +309,6 @@ NSC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
*/


/*
* map SEC_ERROR_xxx to CKR_xxx.
*/
static CK_RV
sftk_MapCryptError(int error)
{
switch (error) {
case SEC_ERROR_INVALID_ARGS:
return CKR_ARGUMENTS_BAD;
case SEC_ERROR_INPUT_LEN:
return CKR_DATA_LEN_RANGE;
case SEC_ERROR_OUTPUT_LEN:
return CKR_BUFFER_TOO_SMALL;
}
return CKR_DEVICE_ERROR;
}

/*
* return a context based on the SFTKContext type.
*/
Expand Down Expand Up @@ -844,10 +890,7 @@ CK_RV NSC_EncryptUpdate(CK_SESSION_HANDLE hSession,
rv = (*context->update)(context->cipherInfo,pEncryptedPart,
&outlen, maxout, pPart, ulPartLen);
*pulEncryptedPartLen = (CK_ULONG) (outlen + padoutlen);
if (rv != SECSuccess) {
return sftk_MapCryptError(PORT_GetError());
}
return CKR_OK;
return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
}


Expand Down Expand Up @@ -898,7 +941,7 @@ CK_RV NSC_EncryptFinal(CK_SESSION_HANDLE hSession,
sftk_FreeContext(context);
}
sftk_FreeSession(session);
return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
}

/* NSC_Encrypt encrypts single-part data. */
Expand Down Expand Up @@ -971,7 +1014,7 @@ CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
/* do it: NOTE: this assumes buf size is big enough. */
rv = (*context->update)(context->cipherInfo, pEncryptedData,
&outlen, maxoutlen, pText.data, pText.len);
crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
crv = (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
*pulEncryptedDataLen = (CK_ULONG) outlen;
if (pText.data != pData)
PORT_ZFree(pText.data, pText.len);
Expand Down Expand Up @@ -1051,7 +1094,7 @@ CK_RV NSC_DecryptUpdate(CK_SESSION_HANDLE hSession,
if (context->padDataLength != 0) {
rv = (*context->update)(context->cipherInfo, pPart, &padoutlen,
maxout, context->padBuf, context->blockSize);
if (rv != SECSuccess) return CKR_DEVICE_ERROR;
if (rv != SECSuccess) return sftk_MapDecryptError(PORT_GetError());
pPart += padoutlen;
maxout -= padoutlen;
}
Expand All @@ -1066,7 +1109,7 @@ CK_RV NSC_DecryptUpdate(CK_SESSION_HANDLE hSession,
rv = (*context->update)(context->cipherInfo,pPart, &outlen,
maxout, pEncryptedPart, ulEncryptedPartLen);
*pulPartLen = (CK_ULONG) (outlen + padoutlen);
return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
return (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError());
}


Expand Down Expand Up @@ -1120,7 +1163,7 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
sftk_FreeContext(context);
finish:
sftk_FreeSession(session);
return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
return (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError());
}

/* NSC_Decrypt decrypts encrypted data in a single part. */
Expand Down Expand Up @@ -1168,7 +1211,7 @@ CK_RV NSC_Decrypt(CK_SESSION_HANDLE hSession,
rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
pEncryptedData, ulEncryptedDataLen);
/* XXX need to do MUCH better error mapping than this. */
crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
crv = (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError());
if (rv == SECSuccess && context->doPad) {
CK_ULONG padding = pData[outlen - 1];
if (padding > context->blockSize || !padding) {
Expand Down Expand Up @@ -2068,7 +2111,7 @@ sftk_MACUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
/* encrypt the current padded data */
rv = (*context->update)(context->cipherInfo,context->macBuf,&outlen,
SFTK_MAX_BLOCK_SIZE,context->padBuf,context->blockSize);
if (rv != SECSuccess) return CKR_DEVICE_ERROR;
if (rv != SECSuccess) return sftk_MapCryptError(PORT_GetError());
}

/* save the residual */
Expand All @@ -2087,7 +2130,7 @@ sftk_MACUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
while (ulPartLen) {
rv = (*context->update)(context->cipherInfo, context->padBuf, &outlen,
SFTK_MAX_BLOCK_SIZE, pPart, context->blockSize);
if (rv != SECSuccess) return CKR_DEVICE_ERROR;
if (rv != SECSuccess) return sftk_MapCryptError(PORT_GetError());
/* paranoia.. make sure we exit the loop */
PORT_Assert(ulPartLen >= context->blockSize);
if (ulPartLen < context->blockSize) break;
Expand Down Expand Up @@ -2162,7 +2205,7 @@ CK_RV NSC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
finish:
sftk_FreeSession(session);

return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
}

/* NSC_Sign signs (encrypts with private key) data in a single part,
Expand Down Expand Up @@ -2209,7 +2252,7 @@ CK_RV NSC_Sign(CK_SESSION_HANDLE hSession,
finish:
sftk_FreeSession(session);

return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
}


Expand Down Expand Up @@ -2498,7 +2541,7 @@ CK_RV NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
sftk_SetContextByType(session, SFTK_VERIFY, NULL);
sftk_FreeSession(session);

return (rv == SECSuccess) ? CKR_OK : CKR_SIGNATURE_INVALID;
return (rv == SECSuccess) ? CKR_OK : sftk_MapVerifyError(PORT_GetError());

}

Expand Down Expand Up @@ -2557,7 +2600,7 @@ CK_RV NSC_VerifyFinal(CK_SESSION_HANDLE hSession,
sftk_FreeContext(context);
sftk_SetContextByType(session, SFTK_VERIFY, NULL);
sftk_FreeSession(session);
return (rv == SECSuccess) ? CKR_OK : CKR_SIGNATURE_INVALID;
return (rv == SECSuccess) ? CKR_OK : sftk_MapVerifyError(PORT_GetError());

}

Expand Down Expand Up @@ -2660,7 +2703,7 @@ CK_RV NSC_VerifyRecover(CK_SESSION_HANDLE hSession,
sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, NULL);
finish:
sftk_FreeSession(session);
return (rv == SECSuccess) ? CKR_OK : CKR_SIGNATURE_INVALID;
return (rv == SECSuccess) ? CKR_OK : sftk_MapVerifyError(PORT_GetError());
}

/*
Expand All @@ -2677,7 +2720,7 @@ CK_RV NSC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
CHECK_FORK();

rv = RNG_RandomUpdate(pSeed, ulSeedLen);
return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
}

/* NSC_GenerateRandom generates random data. */
Expand All @@ -2689,7 +2732,11 @@ CK_RV NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
CHECK_FORK();

rv = RNG_GenerateGlobalRandomBytes(pRandomData, ulRandomLen);
return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
/*
* This may fail with SEC_ERROR_NEED_RANDOM, which means the RNG isn't
* seeded with enough entropy.
*/
return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
}

/*
Expand Down Expand Up @@ -2784,7 +2831,7 @@ nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
sftk_fatalError = PR_TRUE;
}
return CKR_DEVICE_ERROR;
return sftk_MapCryptError(PORT_GetError());
}
crv = sftk_AddAttributeType(key,CKA_PRIME,
params->prime.data, params->prime.len);
Expand Down Expand Up @@ -3670,7 +3717,7 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
sftk_fatalError = PR_TRUE;
}
crv = CKR_DEVICE_ERROR;
crv = sftk_MapCryptError(PORT_GetError());
break;
}
/* now fill in the RSA dependent paramenters in the public key */
Expand Down Expand Up @@ -3790,7 +3837,7 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
sftk_fatalError = PR_TRUE;
}
crv = CKR_DEVICE_ERROR;
crv = sftk_MapCryptError(PORT_GetError());
break;
}

Expand Down Expand Up @@ -3863,7 +3910,7 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
sftk_fatalError = PR_TRUE;
}
crv = CKR_DEVICE_ERROR;
crv = sftk_MapCryptError(PORT_GetError());
break;
}

Expand Down Expand Up @@ -3906,7 +3953,7 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
rv = EC_DecodeParams(&ecEncodedParams, &ecParams);
PORT_Free(ecEncodedParams.data);
if (rv != SECSuccess) {
crv = CKR_DEVICE_ERROR;
crv = sftk_MapCryptError(PORT_GetError());
break;
}
rv = EC_NewKey(ecParams, &ecPriv);
Expand All @@ -3915,7 +3962,7 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
sftk_fatalError = PR_TRUE;
}
crv = CKR_DEVICE_ERROR;
crv = sftk_MapCryptError(PORT_GetError());
break;
}

Expand Down Expand Up @@ -5794,7 +5841,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
nsslowkey_DestroyPrivateKey(privKey);

if (rv != SECSuccess) {
crv = CKR_DEVICE_ERROR;
crv = sftk_MapCryptError(PORT_GetError());
break;
}

Expand Down

0 comments on commit 41f42d5

Please sign in to comment.