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 + -
显示快捷键?