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