pkcs11c.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,203 行 · 第 1/5 页
C
2,203 行
/* NSC_Digest digests data in a single part. */CK_RV NSC_Digest(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen){ PK11Session *session; PK11SessionContext *context; unsigned int digestLen; unsigned int maxout = *pulDigestLen; CK_RV crv; /* make sure we're legal */ crv = pk11_GetContext(hSession,&context,PK11_HASH,PR_FALSE,&session); if (crv != CKR_OK) return crv; /* do it: */ (*context->hashUpdate)(context->cipherInfo, pData, ulDataLen); /* NOTE: this assumes buf size is bigenough for the algorithm */ (*context->end)(context->cipherInfo, pDigest, &digestLen,maxout); *pulDigestLen = digestLen; pk11_SetContextByType(session, PK11_HASH, NULL); pk11_FreeContext(context); pk11_FreeSession(session); return CKR_OK;}/* NSC_DigestUpdate continues a multiple-part message-digesting operation. */CK_RV NSC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart, CK_ULONG ulPartLen){ PK11SessionContext *context; CK_RV crv; /* make sure we're legal */ crv = pk11_GetContext(hSession,&context,PK11_HASH,PR_TRUE,NULL); if (crv != CKR_OK) return crv; /* do it: */ (*context->hashUpdate)(context->cipherInfo, pPart, ulPartLen); return CKR_OK;}/* NSC_DigestFinal finishes a multiple-part message-digesting operation. */CK_RV NSC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen){ PK11Session *session; PK11SessionContext *context; unsigned int maxout = *pulDigestLen; unsigned int digestLen; CK_RV crv; /* make sure we're legal */ crv = pk11_GetContext(hSession, &context, PK11_HASH, PR_TRUE, &session); if (crv != CKR_OK) return crv; if (pDigest != NULL) { (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout); *pulDigestLen = digestLen; } else { *pulDigestLen = 0; } pk11_SetContextByType(session, PK11_HASH, NULL); pk11_FreeContext(context); pk11_FreeSession(session); return CKR_OK;}/* * this helper functions are used by Generic Macing and Signing functions * that use hashes as part of their operations. */static CK_RVpk11_doSubMD2(PK11SessionContext *context) { MD2Context *md2_context = MD2_NewContext(); context->hashInfo = (void *)md2_context; if (context->hashInfo == NULL) { return CKR_HOST_MEMORY; } context->hashUpdate = (PK11Hash) MD2_Update; context->end = (PK11End) MD2_End; context->hashdestroy = (PK11Destroy) MD2_DestroyContext; MD2_Begin(md2_context); return CKR_OK;}static CK_RVpk11_doSubMD5(PK11SessionContext *context) { MD5Context *md5_context = MD5_NewContext(); context->hashInfo = (void *)md5_context; if (context->hashInfo == NULL) { return CKR_HOST_MEMORY; } context->hashUpdate = (PK11Hash) MD5_Update; context->end = (PK11End) MD5_End; context->hashdestroy = (PK11Destroy) MD5_DestroyContext; MD5_Begin(md5_context); return CKR_OK;}static CK_RVpk11_doSubSHA1(PK11SessionContext *context) { SHA1Context *sha1_context = SHA1_NewContext(); context->hashInfo = (void *)sha1_context; if (context->hashInfo == NULL) { return CKR_HOST_MEMORY; } context->hashUpdate = (PK11Hash) SHA1_Update; context->end = (PK11End) SHA1_End; context->hashdestroy = (PK11Destroy) SHA1_DestroyContext; SHA1_Begin(sha1_context); return CKR_OK;}/* * HMAC General copies only a portion of the result. This update routine likes * the final HMAC output with the signature. */static SECStatuspk11_HMACCopy(CK_ULONG *copyLen,unsigned char *sig,unsigned int *sigLen, unsigned int maxLen,unsigned char *hash, unsigned int hashLen){ if (maxLen < *copyLen) return SECFailure; PORT_Memcpy(sig,hash,*copyLen); *sigLen = *copyLen; return SECSuccess;}/* Verify is just a compare for HMAC */static SECStatuspk11_HMACCmp(CK_ULONG *copyLen,unsigned char *sig,unsigned int sigLen, unsigned char *hash, unsigned int hashLen){ return PORT_Memcmp(sig,hash,*copyLen) ? SECSuccess : SECFailure ;}/* * common HMAC initalization routine */static CK_RVpk11_doHMACInit(PK11SessionContext *context,SECOidTag oid, PK11Object *key, CK_ULONG mac_size){ PK11Attribute *keyval; HMACContext *HMACcontext; CK_ULONG *intpointer; keyval = pk11_FindAttribute(key,CKA_VALUE); if (keyval == NULL) return CKR_KEY_SIZE_RANGE; HMACcontext = HMAC_Create(oid, (const unsigned char*)keyval->attrib.pValue, keyval->attrib.ulValueLen); context->hashInfo = HMACcontext; context->multi = PR_TRUE; pk11_FreeAttribute(keyval); if (context->hashInfo == NULL) { return CKR_HOST_MEMORY; } context->hashUpdate = (PK11Hash) HMAC_Update; context->end = (PK11End) HMAC_Finish; context->hashdestroy = (PK11Destroy) pk11_HMAC_Destroy; intpointer = (CK_ULONG *) PORT_Alloc(sizeof(CK_ULONG)); if (intpointer == NULL) { return CKR_HOST_MEMORY; } *intpointer = mac_size; context->cipherInfo = (void *) intpointer; context->destroy = (PK11Destroy) pk11_Space; context->update = (PK11Cipher) pk11_HMACCopy; context->verify = (PK11Verify) pk11_HMACCmp; HMAC_Begin(HMACcontext); return CKR_OK;}/* * SSL Macing support. SSL Macs are inited, then update with the base * hashing algorithm, then finalized in sign and verify *//* * FROM SSL: * 60 bytes is 3 times the maximum length MAC size that is supported. * We probably should have one copy of this table. We still need this table * in ssl to 'sign' the handshake hashes. */static unsigned char ssl_pad_1 [60] = { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36};static unsigned char ssl_pad_2 [60] = { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c};static SECStatuspk11_SSLMACSign(PK11SSLMACInfo *info,unsigned char *sig,unsigned int *sigLen, unsigned int maxLen,unsigned char *hash, unsigned int hashLen){ unsigned char tmpBuf[PK11_MAX_MAC_LENGTH]; unsigned int out; info->begin(info->hashContext); info->update(info->hashContext,info->key,info->keySize); info->update(info->hashContext,ssl_pad_2,info->padSize); info->update(info->hashContext,hash,hashLen); info->end(info->hashContext,tmpBuf,&out,PK11_MAX_MAC_LENGTH); PORT_Memcpy(sig,tmpBuf,info->macSize); *sigLen = info->macSize; return SECSuccess;}static SECStatuspk11_SSLMACVerify(PK11SSLMACInfo *info,unsigned char *sig,unsigned int sigLen, unsigned char *hash, unsigned int hashLen){ unsigned char tmpBuf[PK11_MAX_MAC_LENGTH]; unsigned int out; info->begin(info->hashContext); info->update(info->hashContext,info->key,info->keySize); info->update(info->hashContext,ssl_pad_2,info->padSize); info->update(info->hashContext,hash,hashLen); info->end(info->hashContext,tmpBuf,&out,PK11_MAX_MAC_LENGTH); return (PORT_Memcmp(sig,tmpBuf,info->macSize) == 0) ? SECSuccess : SECFailure;}/* * common HMAC initalization routine */static CK_RVpk11_doSSLMACInit(PK11SessionContext *context,SECOidTag oid, PK11Object *key, CK_ULONG mac_size){ PK11Attribute *keyval; PK11Begin begin; int padSize; PK11SSLMACInfo *sslmacinfo; CK_RV crv = CKR_MECHANISM_INVALID; if (oid == SEC_OID_SHA1) { crv = pk11_doSubSHA1(context); begin = (PK11Begin) SHA1_Begin; if (crv != CKR_OK) return crv; padSize = 40; } else { crv = pk11_doSubMD5(context); if (crv != CKR_OK) return crv; begin = (PK11Begin) MD5_Begin; padSize = 48; } context->multi = PR_TRUE; keyval = pk11_FindAttribute(key,CKA_VALUE); if (keyval == NULL) return CKR_KEY_SIZE_RANGE; context->hashUpdate(context->hashInfo,keyval->attrib.pValue, keyval->attrib.ulValueLen); context->hashUpdate(context->hashInfo,ssl_pad_1,padSize); sslmacinfo = (PK11SSLMACInfo *) PORT_Alloc(sizeof(PK11SSLMACInfo)); if (sslmacinfo == NULL) { pk11_FreeAttribute(keyval); return CKR_HOST_MEMORY; } sslmacinfo->macSize = mac_size; sslmacinfo->hashContext = context->hashInfo; PORT_Memcpy(sslmacinfo->key,keyval->attrib.pValue, keyval->attrib.ulValueLen); sslmacinfo->keySize = keyval->attrib.ulValueLen; sslmacinfo->begin = begin; sslmacinfo->end = context->end; sslmacinfo->update = context->hashUpdate; sslmacinfo->padSize = padSize; pk11_FreeAttribute(keyval); context->cipherInfo = (void *) sslmacinfo; context->destroy = (PK11Destroy) pk11_Space; context->update = (PK11Cipher) pk11_SSLMACSign; context->verify = (PK11Verify) pk11_SSLMACVerify; return CKR_OK;}typedef struct { PRUint32 cxSize; /* size of allocated block, in bytes. */ PRUint32 cxKeyLen; /* number of bytes of cxBuf containing key. */ PRUint32 cxDataLen; /* number of bytes of cxBuf containing data. */ SECStatus cxRv; /* records failure of void functions. */ unsigned char cxBuf[512]; /* actual size may be larger than 512. */} TLSPRFContext;static voidpk11_TLSPRFHashUpdate(TLSPRFContext *cx, const unsigned char *data, unsigned int data_len){ PRUint32 bytesUsed = PK11_OFFSETOF(TLSPRFContext, cxBuf) + cx->cxKeyLen + cx->cxDataLen; if (cx->cxRv != SECSuccess) /* function has previously failed. */ return; if (bytesUsed + data_len > cx->cxSize) { /* We don't use realloc here because ** (a) realloc doesn't zero out the old block, and ** (b) if realloc fails, we lose the old block. */ PRUint32 blockSize = bytesUsed + data_len + 512; TLSPRFContext *new_cx = (TLSPRFContext *)PORT_Alloc(blockSize); if (!new_cx) { cx->cxRv = SECFailure; return; } PORT_Memcpy(new_cx, cx, cx->cxSize); new_cx->cxSize = blockSize; PORT_ZFree(cx, cx->cxSize); cx = new_cx; } PORT_Memcpy(cx->cxBuf + cx->cxKeyLen + cx->cxDataLen, data, data_len); cx->cxDataLen += data_len;}static void pk11_TLSPRFEnd(TLSPRFContext *ctx, unsigned char *hashout, unsigned int *pDigestLen, unsigned int maxDigestLen){ *pDigestLen = 0; /* tells Verify that no data has been input yet. */}/* Compute the PRF values from the data previously input. */static SECStatuspk11_TLSPRFUpdate(TLSPRFContext *cx, unsigned char *sig, /* output goes here. */ unsigned int * sigLen, /* how much output. */ unsigned int maxLen, /* output buffer size */ unsigned char *hash, /* unused. */ unsigned int hashLen) /* unused. */{ SECStatus rv; SECItem sigItem; SECItem seedItem; SECItem secretItem; if (cx->cxRv != SECSuccess) return cx->cxRv; secretItem.data = cx->cxBuf; secretItem.len = cx->cxKeyLen; seedItem.data = cx->cxBuf + cx->cxKeyLen; seedItem.len = cx->cxDataLen; sigItem.data = sig; sigItem.len = maxLen; rv = pk11_PRF(&secretItem, NULL, &seedItem, &sigItem); if (rv == SECSuccess && sigLen != NULL) *sigLen = sigItem.len; return rv;}static SECStatuspk11_TLSPRFVerify(TLSPRFContext *cx, unsigned char *sig, /* input, for comparison. */ unsigned int sigLen, /* length of sig. */ unsigned char *hash, /* data to be verified. */ unsigned int hashLen) /* size of hash data. */{ unsigned char * tmp = (unsigned char *)PORT_Alloc(sigLen); unsigned int tmpLen = sigLen; SECStatus rv; if (!tmp) return SECFailure; if (hashLen) { /* hashLen is non-zero when the user does a one-step verify. ** In this case, none of the data has been input yet. */ pk11_TLSPRFHashUpdate(cx, hash, hashLen); } rv = pk11_TLSPRFUpdate(cx, tmp, &tmpLen, sigLen, NULL, 0); if (rv == SECSuccess) { rv = (SECStatus)(1 - !PORT_Memcmp(tmp, sig, sigLen)); } PORT_ZFree(tmp, sigLen); return rv;}static voidpk11_TLSPRFHashDestroy(TLSPRFContext *cx, PRBool freeit){ if (freeit) PORT_ZFree(cx, cx->cxSize);}static CK_RVpk11_TLSPRFInit(PK11SessionContext *context, PK11Object * key, CK_KEY_TYPE key_type){ PK11Attribute * keyVal; TLSPRFContext * prf_cx; CK_RV crv = CKR_HOST_MEMORY; PRUint32 keySize; PRUint32 blockSize; if (key_type != CKK_GENERIC_SECRET) return CKR_KEY_TYPE_INCONSISTENT; /* CKR_KEY_FUNCTION_NOT_PERMITTED */ context->multi = PR_TRUE; keyVal = pk11_FindAttribute(key, CKA_VALUE); keySize = (!keyVal) ? 0 : keyVal->attrib.ulValueLen; blockSize = keySize + sizeof(TLSPRFContext); prf_cx = (TLSPRFContext *)PORT_Alloc(blockSize); if (!prf_cx) goto done; prf_cx->cxSize = blockSize; prf_cx->cxKeyLen = keySize; prf_cx->cxDataLen = 0; prf_cx->cxRv = SECSuccess; if (keySize) PORT_Memcpy(prf_cx->cxBuf, keyVal->attrib.pValue, keySize); context->hashInfo = (void *) prf_cx;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?