diff options
Diffstat (limited to 'security/nss/lib/pkcs7/p7common.c')
-rw-r--r-- | security/nss/lib/pkcs7/p7common.c | 738 |
1 files changed, 0 insertions, 738 deletions
diff --git a/security/nss/lib/pkcs7/p7common.c b/security/nss/lib/pkcs7/p7common.c deleted file mode 100644 index e11a7f586..000000000 --- a/security/nss/lib/pkcs7/p7common.c +++ /dev/null @@ -1,738 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * PKCS7 implementation -- the exported parts that are used whether - * creating or decoding. - * - * $Id$ - */ - -#include "p7local.h" - -#include "cert.h" -#include "secitem.h" -#include "secoid.h" -#include "secpkcs5.h" -#include "pk11func.h" - -/* - * Find out (saving pointer to lookup result for future reference) - * and return the inner content type. - */ -SECOidTag -SEC_PKCS7ContentType (SEC_PKCS7ContentInfo *cinfo) -{ - if (cinfo->contentTypeTag == NULL) - cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); - - if (cinfo->contentTypeTag == NULL) - return SEC_OID_UNKNOWN; - - return cinfo->contentTypeTag->offset; -} - - -/* - * Destroy a PKCS7 contentInfo and all of its sub-pieces. - */ -void -SEC_PKCS7DestroyContentInfo(SEC_PKCS7ContentInfo *cinfo) -{ - SECOidTag kind; - CERTCertificate **certs; - CERTCertificateList **certlists; - SEC_PKCS7SignerInfo **signerinfos; - SEC_PKCS7RecipientInfo **recipientinfos; - - PORT_Assert (cinfo->refCount > 0); - if (cinfo->refCount <= 0) - return; - - cinfo->refCount--; - if (cinfo->refCount > 0) - return; - - certs = NULL; - certlists = NULL; - recipientinfos = NULL; - signerinfos = NULL; - - kind = SEC_PKCS7ContentType (cinfo); - switch (kind) { - case SEC_OID_PKCS7_ENVELOPED_DATA: - { - SEC_PKCS7EnvelopedData *edp; - - edp = cinfo->content.envelopedData; - if (edp != NULL) { - recipientinfos = edp->recipientInfos; - } - } - break; - case SEC_OID_PKCS7_SIGNED_DATA: - { - SEC_PKCS7SignedData *sdp; - - sdp = cinfo->content.signedData; - if (sdp != NULL) { - certs = sdp->certs; - certlists = sdp->certLists; - signerinfos = sdp->signerInfos; - } - } - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saedp; - - saedp = cinfo->content.signedAndEnvelopedData; - if (saedp != NULL) { - certs = saedp->certs; - certlists = saedp->certLists; - recipientinfos = saedp->recipientInfos; - signerinfos = saedp->signerInfos; - if (saedp->sigKey != NULL) - PK11_FreeSymKey (saedp->sigKey); - } - } - break; - default: - /* XXX Anything else that needs to be "manually" freed/destroyed? */ - break; - } - - if (certs != NULL) { - CERTCertificate *cert; - - while ((cert = *certs++) != NULL) { - CERT_DestroyCertificate (cert); - } - } - - if (certlists != NULL) { - CERTCertificateList *certlist; - - while ((certlist = *certlists++) != NULL) { - CERT_DestroyCertificateList (certlist); - } - } - - if (recipientinfos != NULL) { - SEC_PKCS7RecipientInfo *ri; - - while ((ri = *recipientinfos++) != NULL) { - if (ri->cert != NULL) - CERT_DestroyCertificate (ri->cert); - } - } - - if (signerinfos != NULL) { - SEC_PKCS7SignerInfo *si; - - while ((si = *signerinfos++) != NULL) { - if (si->cert != NULL) - CERT_DestroyCertificate (si->cert); - if (si->certList != NULL) - CERT_DestroyCertificateList (si->certList); - } - } - - if (cinfo->poolp != NULL) { - PORT_FreeArena (cinfo->poolp, PR_FALSE); /* XXX clear it? */ - } -} - - -/* - * Return a copy of the given contentInfo. The copy may be virtual - * or may be real -- either way, the result needs to be passed to - * SEC_PKCS7DestroyContentInfo later (as does the original). - */ -SEC_PKCS7ContentInfo * -SEC_PKCS7CopyContentInfo(SEC_PKCS7ContentInfo *cinfo) -{ - if (cinfo == NULL) - return NULL; - - PORT_Assert (cinfo->refCount > 0); - - if (cinfo->created) { - /* - * Want to do a real copy of these; otherwise subsequent - * changes made to either copy are likely to be a surprise. - * XXX I suspect that this will not actually be called for yet, - * which is why the assert, so to notice if it is... - */ - PORT_Assert (0); - /* - * XXX Create a new pool here, and copy everything from - * within. For cert stuff, need to call the appropriate - * copy functions, etc. - */ - } - - cinfo->refCount++; - return cinfo; -} - - -/* - * Return a pointer to the actual content. In the case of those types - * which are encrypted, this returns the *plain* content. - * XXX Needs revisiting if/when we handle nested encrypted types. - */ -SECItem * -SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo) -{ - SECOidTag kind; - - kind = SEC_PKCS7ContentType (cinfo); - switch (kind) { - case SEC_OID_PKCS7_DATA: - return cinfo->content.data; - case SEC_OID_PKCS7_DIGESTED_DATA: - { - SEC_PKCS7DigestedData *digd; - - digd = cinfo->content.digestedData; - if (digd == NULL) - break; - return SEC_PKCS7GetContent (&(digd->contentInfo)); - } - case SEC_OID_PKCS7_ENCRYPTED_DATA: - { - SEC_PKCS7EncryptedData *encd; - - encd = cinfo->content.encryptedData; - if (encd == NULL) - break; - return &(encd->encContentInfo.plainContent); - } - case SEC_OID_PKCS7_ENVELOPED_DATA: - { - SEC_PKCS7EnvelopedData *envd; - - envd = cinfo->content.envelopedData; - if (envd == NULL) - break; - return &(envd->encContentInfo.plainContent); - } - case SEC_OID_PKCS7_SIGNED_DATA: - { - SEC_PKCS7SignedData *sigd; - - sigd = cinfo->content.signedData; - if (sigd == NULL) - break; - return SEC_PKCS7GetContent (&(sigd->contentInfo)); - } - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saed; - - saed = cinfo->content.signedAndEnvelopedData; - if (saed == NULL) - break; - return &(saed->encContentInfo.plainContent); - } - default: - PORT_Assert(0); - break; - } - - return NULL; -} - - -/* - * XXX Fix the placement and formatting of the - * following routines (i.e. make them consistent with the rest of - * the pkcs7 code -- I think some/many belong in other files and - * they all need a formatting/style rehaul) - */ - -/* retrieve the algorithm identifier for encrypted data. - * the identifier returned is a copy of the algorithm identifier - * in the content info and needs to be freed after being used. - * - * cinfo is the content info for which to retrieve the - * encryption algorithm. - * - * if the content info is not encrypted data or an error - * occurs NULL is returned. - */ -SECAlgorithmID * -SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo) -{ - SECAlgorithmID *alg = 0; - switch (SEC_PKCS7ContentType(cinfo)) - { - case SEC_OID_PKCS7_ENCRYPTED_DATA: - alg = &cinfo->content.encryptedData->encContentInfo.contentEncAlg; - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - alg = &cinfo->content.envelopedData->encContentInfo.contentEncAlg; - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - alg = &cinfo->content.signedAndEnvelopedData - ->encContentInfo.contentEncAlg; - break; - default: - alg = 0; - break; - } - - return alg; -} - -/* set the content of the content info. For data content infos, - * the data is set. For encrytped content infos, the plainContent - * is set, and is expected to be encrypted later. - * - * cinfo is the content info where the data will be set - * - * buf is a buffer of the data to set - * - * len is the length of the data being set. - * - * in the event of an error, SECFailure is returned. SECSuccess - * indicates the content was successfully set. - */ -SECStatus -SEC_PKCS7SetContent(SEC_PKCS7ContentInfo *cinfo, - const char *buf, - unsigned long len) -{ - SECOidTag cinfo_type; - SECStatus rv; - SECItem content; - SECOidData *contentTypeTag = NULL; - - content.data = (unsigned char *)buf; - content.len = len; - - cinfo_type = SEC_PKCS7ContentType(cinfo); - - /* set inner content */ - switch(cinfo_type) - { - case SEC_OID_PKCS7_SIGNED_DATA: - if(content.len > 0) { - /* we "leak" the old content here, but as it's all in the pool */ - /* it does not really matter */ - - /* create content item if necessary */ - if (cinfo->content.signedData->contentInfo.content.data == NULL) - cinfo->content.signedData->contentInfo.content.data = SECITEM_AllocItem(cinfo->poolp, NULL, 0); - rv = SECITEM_CopyItem(cinfo->poolp, - cinfo->content.signedData->contentInfo.content.data, - &content); - } else { - cinfo->content.signedData->contentInfo.content.data->data = NULL; - cinfo->content.signedData->contentInfo.content.data->len = 0; - rv = SECSuccess; - } - if(rv == SECFailure) - goto loser; - - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - /* 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; - } -} - - -int -SEC_PKCS7GetKeyLength(SEC_PKCS7ContentInfo *cinfo) -{ - if (cinfo->contentTypeTag->offset == SEC_OID_PKCS7_ENVELOPED_DATA) - return cinfo->content.envelopedData->encContentInfo.keysize; - else - return 0; -} - |