p7common.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 739 行 · 第 1/2 页

C
739
字号
	    /* XXX this forces the inner content type to be "data" */	    /* do we really want to override without asking or reason? */	    contentTypeTag = SECOID_FindOIDByTag(SEC_OID_PKCS7_DATA);	    if(contentTypeTag == NULL)		goto loser;	    rv = SECITEM_CopyItem(cinfo->poolp, 		&(cinfo->content.encryptedData->encContentInfo.contentType),		&(contentTypeTag->oid));	    if(rv == SECFailure)		goto loser;	    if(content.len > 0) {		rv = SECITEM_CopyItem(cinfo->poolp, 			&(cinfo->content.encryptedData->encContentInfo.plainContent),			&content);	    } else {		cinfo->content.encryptedData->encContentInfo.plainContent.data = NULL;		cinfo->content.encryptedData->encContentInfo.encContent.data = NULL;		cinfo->content.encryptedData->encContentInfo.plainContent.len = 0;		cinfo->content.encryptedData->encContentInfo.encContent.len = 0;		rv = SECSuccess;	    }	    if(rv == SECFailure)		goto loser;	    break;	case SEC_OID_PKCS7_DATA:	    cinfo->content.data = (SECItem *)PORT_ArenaZAlloc(cinfo->poolp,		sizeof(SECItem));	    if(cinfo->content.data == NULL)		goto loser;	    if(content.len > 0) {		rv = SECITEM_CopyItem(cinfo->poolp,			cinfo->content.data, &content);	    } else {	    	/* handle case with NULL content */		rv = SECSuccess;	    }	    if(rv == SECFailure)		goto loser;	    break;	default:	    goto loser;    }    return SECSuccess;loser:	    return SECFailure;}/* the content of an encrypted data content info is encrypted. * it is assumed that for encrypted data, that the data has already * been set and is in the "plainContent" field of the content info. * * cinfo is the content info to encrypt * * key is the key with which to perform the encryption.  if the *     algorithm is a password based encryption algorithm, the *     key is actually a password which will be processed per *     PKCS #5. *  * in the event of an error, SECFailure is returned.  SECSuccess * indicates a success. */SECStatus SEC_PKCS7EncryptContents(PRArenaPool *poolp,			 SEC_PKCS7ContentInfo *cinfo,			 SECItem *key,			 void *wincx){    SECAlgorithmID *algid 	= NULL;    SECItem *       result 	= NULL;    SECItem *       src;    SECItem *       dest;    SECItem *       blocked_data = NULL;    void *          mark;    void *          cx;    PK11SymKey *    eKey 	= NULL;    PK11SlotInfo *  slot 	= NULL;    CK_MECHANISM    pbeMech;    CK_MECHANISM    cryptoMech;    int             bs;    SECOidTag       algtag;    SECStatus       rv 		= SECFailure;    SECItem         c_param;    if((cinfo == NULL) || (key == NULL))	return SECFailure;    if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA)	return SECFailure;    algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);	    if(algid == NULL)	return SECFailure;    if(poolp == NULL)	poolp = cinfo->poolp;    mark = PORT_ArenaMark(poolp);        src = &cinfo->content.encryptedData->encContentInfo.plainContent;    dest = &cinfo->content.encryptedData->encContentInfo.encContent;    algtag = SECOID_GetAlgorithmTag(algid);    c_param.data = NULL;    dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64));    dest->len = (src->len + 64);    if(dest->data == NULL) {	rv = SECFailure;	goto loser;    }    slot = PK11_GetInternalKeySlot();    if(slot == NULL) {	rv = SECFailure;	goto loser;    }    eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx);    if(eKey == NULL) {	rv = SECFailure;	goto loser;    }    pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);    result = PK11_ParamFromAlgid(algid);    pbeMech.pParameter = result->data;    pbeMech.ulParameterLen = result->len;    if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, key, 			PR_FALSE) != CKR_OK) {	rv = SECFailure;	goto loser;    }    c_param.data = (unsigned char *)cryptoMech.pParameter;    c_param.len = cryptoMech.ulParameterLen;    /* block according to PKCS 8 */    bs = PK11_GetBlockSize(cryptoMech.mechanism, &c_param);    rv = SECSuccess;    if(bs) {	char pad_char;	pad_char = (char)(bs - (src->len % bs));	if(src->len % bs) {	    rv = SECSuccess;	    blocked_data = PK11_BlockData(src, bs);	    if(blocked_data) {		PORT_Memset((blocked_data->data + blocked_data->len - (int)pad_char), 			    pad_char, (int)pad_char);	    } else {		rv = SECFailure;		goto loser;	    }	} else {	    blocked_data = SECITEM_DupItem(src);	    if(blocked_data) {		blocked_data->data = (unsigned char*)PORT_Realloc(						  blocked_data->data,						  blocked_data->len + bs);		if(blocked_data->data) {		    blocked_data->len += bs;		    PORT_Memset((blocked_data->data + src->len), (char)bs, bs);		} else {		    rv = SECFailure;		    goto loser;		}	    } else {		rv = SECFailure;		goto loser;	    }	 }    } else {	blocked_data = SECITEM_DupItem(src);	if(!blocked_data) {	    rv = SECFailure;	    goto loser;	}    }    cx = PK11_CreateContextBySymKey(cryptoMech.mechanism, CKA_ENCRYPT,		    		    eKey, &c_param);    if(cx == NULL) {	rv = SECFailure;	goto loser;    }    rv = PK11_CipherOp((PK11Context*)cx, dest->data, (int *)(&dest->len), 		       (int)(src->len + 64), blocked_data->data, 		       (int)blocked_data->len);    PK11_DestroyContext((PK11Context*)cx, PR_TRUE);loser:    /* let success fall through */    if(blocked_data != NULL)	SECITEM_ZfreeItem(blocked_data, PR_TRUE);    if(result != NULL)	SECITEM_ZfreeItem(result, PR_TRUE);    if(rv == SECFailure)	PORT_ArenaRelease(poolp, mark);    else 	PORT_ArenaUnmark(poolp, mark);    if(eKey != NULL)	PK11_FreeSymKey(eKey);    if(slot != NULL)	PK11_FreeSlot(slot);    if(c_param.data != NULL) 	SECITEM_ZfreeItem(&c_param, PR_FALSE);	    return rv;}/* the content of an encrypted data content info is decrypted. * it is assumed that for encrypted data, that the data has already * been set and is in the "encContent" field of the content info. * * cinfo is the content info to decrypt * * key is the key with which to perform the decryption.  if the *     algorithm is a password based encryption algorithm, the *     key is actually a password which will be processed per *     PKCS #5. *  * in the event of an error, SECFailure is returned.  SECSuccess * indicates a success. */SECStatus SEC_PKCS7DecryptContents(PRArenaPool *poolp,			 SEC_PKCS7ContentInfo *cinfo,			 SECItem *key,			 void *wincx){    SECAlgorithmID *algid = NULL;    SECOidTag algtag;    SECStatus rv = SECFailure;    SECItem *result = NULL, *dest, *src;    void *mark;    PK11SymKey *eKey = NULL;    PK11SlotInfo *slot = NULL;    CK_MECHANISM pbeMech, cryptoMech;    void *cx;    SECItem c_param;    int bs;    if((cinfo == NULL) || (key == NULL))	return SECFailure;    if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA)	return SECFailure;    algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);	    if(algid == NULL)	return SECFailure;    if(poolp == NULL)	poolp = cinfo->poolp;    mark = PORT_ArenaMark(poolp);        src = &cinfo->content.encryptedData->encContentInfo.encContent;    dest = &cinfo->content.encryptedData->encContentInfo.plainContent;    algtag = SECOID_GetAlgorithmTag(algid);    c_param.data = NULL;    dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64));    dest->len = (src->len + 64);    if(dest->data == NULL) {	rv = SECFailure;	goto loser;    }    slot = PK11_GetInternalKeySlot();    if(slot == NULL) {	rv = SECFailure;	goto loser;    }    eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx);    if(eKey == NULL) {	rv = SECFailure;	goto loser;    }    pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);    result = PK11_ParamFromAlgid(algid);    pbeMech.pParameter = result->data;    pbeMech.ulParameterLen = result->len;    if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, key,			PR_FALSE) != CKR_OK) {	rv = SECFailure;	goto loser;    }    c_param.data = (unsigned char *)cryptoMech.pParameter;    c_param.len = cryptoMech.ulParameterLen;    cx = PK11_CreateContextBySymKey(cryptoMech.mechanism, CKA_DECRYPT,		    		    eKey, &c_param);    if(cx == NULL) {	rv = SECFailure;	goto loser;    }    rv = PK11_CipherOp((PK11Context*)cx, dest->data, (int *)(&dest->len), 		       (int)(src->len + 64), src->data, (int)src->len);    PK11_DestroyContext((PK11Context *)cx, PR_TRUE);    bs = PK11_GetBlockSize(cryptoMech.mechanism, &c_param);    if(bs) {	/* check for proper badding in block algorithms.  this assumes	 * RC2 cbc or a DES cbc variant.  and the padding is thus defined	 */	if(((int)dest->data[dest->len-1] <= bs) && 	   ((int)dest->data[dest->len-1] > 0)) {	    dest->len -= (int)dest->data[dest->len-1];	} else {	    rv = SECFailure;	    /* set an error ? */	}    } loser:    /* let success fall through */    if(result != NULL)	SECITEM_ZfreeItem(result, PR_TRUE);    if(rv == SECFailure)	PORT_ArenaRelease(poolp, mark);    else	PORT_ArenaUnmark(poolp, mark);    if(eKey != NULL)	PK11_FreeSymKey(eKey);    if(slot != NULL)	PK11_FreeSlot(slot);    if(c_param.data != NULL) 	SECITEM_ZfreeItem(&c_param, PR_FALSE);	    return rv;}SECItem **SEC_PKCS7GetCertificateList(SEC_PKCS7ContentInfo *cinfo){    switch(SEC_PKCS7ContentType(cinfo))    {	case SEC_OID_PKCS7_SIGNED_DATA:	    return cinfo->content.signedData->rawCerts;	    break;	default:	    return NULL;	    break;    }}intSEC_PKCS7GetKeyLength(SEC_PKCS7ContentInfo *cinfo){  if (cinfo->contentTypeTag->offset == SEC_OID_PKCS7_ENVELOPED_DATA)    return cinfo->content.envelopedData->encContentInfo.keysize;  else    return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?