secpkcs5.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,828 行 · 第 1/4 页
C
1,828 行
} pbe_param = sec_pkcs5_convert_algid(algid); if(!pbe_param) { return NULL; } iv = sec_pkcs5_compute_iv(pbe_param, pwitem, faulty3DES); sec_pkcs5_destroy_pbe_param(pbe_param); return iv;}/* generate the key * a 0 length password is allowed. corresponds to a key generated * from just the salt. */SECItem *SEC_PKCS5GetKey(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES){ SECItem *key; SEC_PKCS5PBEParameter *pbe_param; if((algid == NULL) || (pwitem == NULL)) { return NULL; } pbe_param = sec_pkcs5_convert_algid(algid); if(pbe_param == NULL) { return NULL; } key = sec_pkcs5_compute_key(pbe_param, pwitem, faulty3DES); sec_pkcs5_destroy_pbe_param(pbe_param); return key;}/* retrieve the salt */SECItem *SEC_PKCS5GetSalt(SECAlgorithmID *algid){ SECItem *salt; SEC_PKCS5PBEParameter *pbe_param; if(algid == NULL) return NULL; pbe_param = sec_pkcs5_convert_algid(algid); if(pbe_param == NULL) return NULL; if(pbe_param->salt.data) { salt = SECITEM_DupItem(&pbe_param->salt); } else { salt = NULL; } sec_pkcs5_destroy_pbe_param(pbe_param); return salt;}/* check to see if an oid is a pbe algorithm */ PRBool SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid){ SECOidTag algorithm; algorithm = SECOID_GetAlgorithmTag(algid); if(sec_pkcs5_hash_algorithm(algorithm) == SEC_OID_UNKNOWN) { return PR_FALSE; } return PR_TRUE;}int SEC_PKCS5GetKeyLength(SECAlgorithmID *algid){ SEC_PKCS5PBEParameter *pbe_param; int keyLen = -1; if(algid == NULL) return -1; pbe_param = sec_pkcs5_convert_algid(algid); if(pbe_param == NULL) return -1; keyLen = sec_pkcs5_key_length(pbe_param->algorithm); sec_pkcs5_destroy_pbe_param(pbe_param); return keyLen;}/* maps crypto algorithm from PBE algorithm. */SECOidTag SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid){ SEC_PKCS5PBEParameter *pbe_param; if(algid == NULL) return SEC_OID_UNKNOWN; pbe_param = sec_pkcs5_convert_algid(algid); if(pbe_param == NULL) return SEC_OID_UNKNOWN; switch(pbe_param->algorithm) { case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: return SEC_OID_DES_EDE3_CBC; case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: return SEC_OID_DES_CBC; case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: return SEC_OID_RC2_CBC; case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: return SEC_OID_RC4; default: break; } sec_pkcs5_destroy_pbe_param(pbe_param); return SEC_OID_UNKNOWN;}/* maps PBE algorithm from crypto algorithm, assumes SHA1 hashing. */SECOidTag SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen){ switch(algTag) { case SEC_OID_DES_EDE3_CBC: switch(keyLen) { case 168: case 192: return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC; case 128: case 92: return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC; default: break; } break; case SEC_OID_DES_CBC: return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC; case SEC_OID_RC2_CBC: switch(keyLen) { case 40: return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC; case 128: return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC; default: break; } break; case SEC_OID_RC4: switch(keyLen) { case 40: return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4; case 128: return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4; default: break; } break; default: break; } return SEC_OID_UNKNOWN;}/* zero length password and salts are allowed. however, the items * containing the salt and password must be non-null. */PBEBitGenContext *PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose, SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded, unsigned int iterations){ PRArenaPool *arena = NULL; PBEBitGenContext *pbeCtxt = NULL; HASH_HashType pbeHash; int vbytes, ubytes; unsigned int c; if(!pwitem || !salt) { return NULL; } arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if(!arena) { return NULL; } pbeCtxt = (PBEBitGenContext*)PORT_ArenaZAlloc(arena, sizeof(PBEBitGenContext)); if(!pbeCtxt) { goto loser; } switch(hashAlgorithm) { case SEC_OID_MD2: pbeHash = HASH_AlgMD2; break; case SEC_OID_MD5: pbeHash = HASH_AlgMD5; break; case SEC_OID_SHA1: pbeHash = HASH_AlgSHA1; break; default: goto loser; } pbeCtxt->hashObject = &SECRawHashObjects[pbeHash]; PORT_Memcpy(&pbeCtxt->pbeParams, &pbeHashAlgorithmParams[pbeHash], sizeof(pbeBitGenParameters)); PORT_Assert(pbeCtxt->pbeParams.hashAlgorithm == hashAlgorithm); vbytes = pbeCtxt->pbeParams.v / 8; ubytes = pbeCtxt->pbeParams.u / 8; c = (bitsNeeded / pbeCtxt->pbeParams.u); c += ((bitsNeeded - (pbeCtxt->pbeParams.u * c)) > 0) ? 1 : 0; pbeCtxt->c = c; pbeCtxt->n = bitsNeeded; pbeCtxt->iterations = iterations; /* allocate buffers */ pbeCtxt->D.len = vbytes; pbeCtxt->S.len = (((salt->len * 8) / pbeCtxt->pbeParams.v) + ((((salt->len * 8) % pbeCtxt->pbeParams.v) > 0) ? 1 : 0)) * vbytes; pbeCtxt->P.len = (((pwitem->len * 8) / pbeCtxt->pbeParams.v) + ((((pwitem->len * 8) % pbeCtxt->pbeParams.v) > 0) ? 1 : 0)) * vbytes; pbeCtxt->I.len = pbeCtxt->S.len + pbeCtxt->P.len; pbeCtxt->A.len = c * ubytes; pbeCtxt->B.len = pbeCtxt->D.len; pbeCtxt->D.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->D.len); if(pbeCtxt->S.len) { pbeCtxt->S.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->S.len); } if(pbeCtxt->P.len) { pbeCtxt->P.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->P.len); } if(pbeCtxt->I.len) { pbeCtxt->I.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->I.len); } pbeCtxt->A.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->A.len); pbeCtxt->B.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->B.len); if(!pbeCtxt->D.data || !pbeCtxt->A.data || !pbeCtxt->B.data || (!pbeCtxt->S.data && pbeCtxt->S.len) || (!pbeCtxt->P.data && pbeCtxt->P.len) || (!pbeCtxt->I.data && pbeCtxt->I.len)) { goto loser; } PORT_Memset(pbeCtxt->D.data, (char)bitGenPurpose, pbeCtxt->D.len); if(pbeCtxt->P.len) { unsigned int z = 0; while(z < pbeCtxt->P.len) { PORT_Memcpy(&(pbeCtxt->P.data[z]), pwitem->data, ((z + pwitem->len > pbeCtxt->P.len) ? (pbeCtxt->P.len - z) : (pwitem->len))); z += pwitem->len; } } if(pbeCtxt->S.len) { unsigned int z = 0; while(z < pbeCtxt->S.len) { PORT_Memcpy(&(pbeCtxt->S.data[z]), salt->data, ((z + salt->len > pbeCtxt->S.len) ? (pbeCtxt->S.len - z) : (salt->len))); z += salt->len; } } if(pbeCtxt->I.len) { if(pbeCtxt->S.len) { PORT_Memcpy(pbeCtxt->I.data, pbeCtxt->S.data, pbeCtxt->S.len); } if(pbeCtxt->P.len) { PORT_Memcpy(&(pbeCtxt->I.data[pbeCtxt->S.len]), pbeCtxt->P.data, pbeCtxt->P.len); } } pbeCtxt->arena = arena; return pbeCtxt;loser: if(arena) { PORT_FreeArena(arena, PR_TRUE); } return NULL;}SECItem *PBE_GenerateBits(PBEBitGenContext *pbeCtxt){ unsigned int i; SECItem *A, *D, *I, *B, *S, *P; unsigned int u, v, c, z, hashLen, n, iter; unsigned int vbyte, ubyte; unsigned char *iterBuf; void *hash = NULL; if(!pbeCtxt) { return NULL; } A = &pbeCtxt->A; B = &pbeCtxt->B; I = &pbeCtxt->I; D = &pbeCtxt->D; S = &pbeCtxt->S; P = &pbeCtxt->P; u = pbeCtxt->pbeParams.u; v = pbeCtxt->pbeParams.v; vbyte = v / 8; ubyte = u / 8; c = pbeCtxt->c; n = pbeCtxt->n; z = 0; iterBuf = (unsigned char*)PORT_Alloc(ubyte); if(!iterBuf) { goto loser; } for(i = 1; i <= c; i++) { unsigned int Bidx; unsigned int k, j; for(iter = 1; iter <= pbeCtxt->iterations; iter++) { hash = pbeCtxt->hashObject->create(); if(!hash) { goto loser; } pbeCtxt->hashObject->begin(hash); if(iter == 1) { pbeCtxt->hashObject->update(hash, D->data, D->len); pbeCtxt->hashObject->update(hash, I->data, I->len); } else { pbeCtxt->hashObject->update(hash, iterBuf, hashLen); } pbeCtxt->hashObject->end(hash, iterBuf, &hashLen, (ubyte)); pbeCtxt->hashObject->destroy(hash, PR_TRUE); if(hashLen != (ubyte)) { goto loser; } } PORT_Memcpy(&(A->data[z]), iterBuf, (ubyte)); Bidx = 0; while(Bidx < B->len) { PORT_Memcpy(&(B->data[Bidx]), &(A->data[z]), (((Bidx + (ubyte)) > B->len) ? (B->len - Bidx) : (ubyte))); Bidx += (ubyte); } k = (S->len / (vbyte)) + (P->len / (vbyte)); for(j = 0; j < k; j++) { unsigned int byteIdx = (vbyte); unsigned int q, carryBit = 0; while(byteIdx > 0) { q = (unsigned int)I->data[(j * (vbyte)) + byteIdx - 1]; q += (unsigned int)B->data[byteIdx - 1]; q += carryBit; if(byteIdx == (vbyte)) { q += 1; } carryBit = ((q > 255) ? 1 : 0); I->data[(j * (vbyte)) + byteIdx - 1] = (unsigned char)(q & 255); byteIdx--; } } z += (ubyte); } A->len = (n / 8); return SECITEM_DupItem(A);loser: return NULL;} voidPBE_DestroyContext(PBEBitGenContext *pbeCtxt) { if(pbeCtxt) { PORT_FreeArena(pbeCtxt->arena, PR_TRUE); }}SECStatusPBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PRArenaPool *arena, SECAlgorithmID *algId){ CK_PBE_PARAMS *pbe_param; SECItem pbeSalt; SECAlgorithmID *pbeAlgID = NULL; SECStatus rv; if(!param || !algId) { return SECFailure; } pbe_param = (CK_PBE_PARAMS *)param->data; pbeSalt.data = (unsigned char *)pbe_param->pSalt; pbeSalt.len = pbe_param->ulSaltLen; pbeAlgID = SEC_PKCS5CreateAlgorithmID(algTag, &pbeSalt, (int)pbe_param->ulIteration); if(!pbeAlgID) { return SECFailure; } rv = SECOID_CopyAlgorithmID(arena, algId, pbeAlgID); SECOID_DestroyAlgorithmID(pbeAlgID, PR_TRUE); return rv;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?