diff options
Diffstat (limited to 'security/nss/lib/smime')
32 files changed, 0 insertions, 13459 deletions
diff --git a/security/nss/lib/smime/Makefile b/security/nss/lib/smime/Makefile deleted file mode 100644 index 3bc1a719a..000000000 --- a/security/nss/lib/smime/Makefile +++ /dev/null @@ -1,80 +0,0 @@ -#! gmake -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# 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 the Initial Developer are Copyright (C) 1994-2000 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -####################################################################### -# (1) Include initial platform-independent assignments (MANDATORY). # -####################################################################### - -include manifest.mn - -####################################################################### -# (2) Include "global" configuration information. (OPTIONAL) # -####################################################################### - -include $(CORE_DEPTH)/coreconf/config.mk - -####################################################################### -# (3) Include "component" configuration information. (OPTIONAL) # -####################################################################### - - - -####################################################################### -# (4) Include "local" platform-dependent assignments (OPTIONAL). # -####################################################################### - -include config.mk - -####################################################################### -# (5) Execute "global" rules. (OPTIONAL) # -####################################################################### - -include $(CORE_DEPTH)/coreconf/rules.mk - -####################################################################### -# (6) Execute "component" rules. (OPTIONAL) # -####################################################################### - - - -####################################################################### -# (7) Execute "local" rules. (OPTIONAL). # -####################################################################### - - - diff --git a/security/nss/lib/smime/cms.h b/security/nss/lib/smime/cms.h deleted file mode 100644 index 034f1ae6c..000000000 --- a/security/nss/lib/smime/cms.h +++ /dev/null @@ -1,1141 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * Interfaces of the CMS implementation. - * - * $Id$ - */ - -#ifndef _CMS_H_ -#define _CMS_H_ - -#include "seccomon.h" - -#include "secoidt.h" -#include "certt.h" -#include "keyt.h" -#include "hasht.h" -#include "cmst.h" - -/************************************************************************/ -SEC_BEGIN_PROTOS - -/************************************************************************ - * cmsdecode.c - CMS decoding - ************************************************************************/ - -/* - * NSS_CMSDecoder_Start - set up decoding of a DER-encoded CMS message - * - * "poolp" - pointer to arena for message, or NULL if new pool should be created - * "cb", "cb_arg" - callback function and argument for delivery of inner content - * inner content will be stored in the message if cb is NULL. - * "pwfn", pwfn_arg" - callback function for getting token password - * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData - */ -extern NSSCMSDecoderContext * -NSS_CMSDecoder_Start(PRArenaPool *poolp, - NSSCMSContentCallback cb, void *cb_arg, - PK11PasswordFunc pwfn, void *pwfn_arg, - NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg); - -/* - * NSS_CMSDecoder_Update - feed DER-encoded data to decoder - */ -extern SECStatus -NSS_CMSDecoder_Update(NSSCMSDecoderContext *p7dcx, const char *buf, unsigned long len); - -/* - * NSS_CMSDecoder_Cancel - cancel a decoding process - */ -extern void -NSS_CMSDecoder_Cancel(NSSCMSDecoderContext *p7dcx); - -/* - * NSS_CMSDecoder_Finish - mark the end of inner content and finish decoding - */ -extern NSSCMSMessage * -NSS_CMSDecoder_Finish(NSSCMSDecoderContext *p7dcx); - -/* - * NSS_CMSMessage_CreateFromDER - decode a CMS message from DER encoded data - */ -extern NSSCMSMessage * -NSS_CMSMessage_CreateFromDER(SECItem *DERmessage, - NSSCMSContentCallback cb, void *cb_arg, - PK11PasswordFunc pwfn, void *pwfn_arg, - NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg); - -/************************************************************************ - * cmsencode.c - CMS encoding - ************************************************************************/ - -/* - * NSS_CMSEncoder_Start - set up encoding of a CMS message - * - * "cmsg" - message to encode - * "outputfn", "outputarg" - callback function for delivery of DER-encoded output - * will not be called if NULL. - * "dest" - if non-NULL, pointer to SECItem that will hold the DER-encoded output - * "destpoolp" - pool to allocate DER-encoded output in - * "pwfn", pwfn_arg" - callback function for getting token password - * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData - * "detached_digestalgs", "detached_digests" - digests from detached content - */ -extern NSSCMSEncoderContext * -NSS_CMSEncoder_Start(NSSCMSMessage *cmsg, - NSSCMSContentCallback outputfn, void *outputarg, - SECItem *dest, PLArenaPool *destpoolp, - PK11PasswordFunc pwfn, void *pwfn_arg, - NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg, - SECAlgorithmID **detached_digestalgs, SECItem **detached_digests); - -/* - * NSS_CMSEncoder_Update - take content data delivery from the user - * - * "p7ecx" - encoder context - * "data" - content data - * "len" - length of content data - */ -extern SECStatus -NSS_CMSEncoder_Update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len); - -/* - * NSS_CMSEncoder_Cancel - stop all encoding - */ -extern SECStatus -NSS_CMSEncoder_Cancel(NSSCMSEncoderContext *p7ecx); - -/* - * NSS_CMSEncoder_Finish - signal the end of data - * - * we need to walk down the chain of encoders and the finish them from the innermost out - */ -extern SECStatus -NSS_CMSEncoder_Finish(NSSCMSEncoderContext *p7ecx); - -/************************************************************************ - * cmsmessage.c - CMS message object - ************************************************************************/ - -/* - * NSS_CMSMessage_Create - create a CMS message object - * - * "poolp" - arena to allocate memory from, or NULL if new arena should be created - */ -extern NSSCMSMessage * -NSS_CMSMessage_Create(PLArenaPool *poolp); - -/* - * NSS_CMSMessage_SetEncodingParams - set up a CMS message object for encoding or decoding - * - * "cmsg" - message object - * "pwfn", pwfn_arg" - callback function for getting token password - * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData - * "detached_digestalgs", "detached_digests" - digests from detached content - * - * used internally. - */ -extern void -NSS_CMSMessage_SetEncodingParams(NSSCMSMessage *cmsg, - PK11PasswordFunc pwfn, void *pwfn_arg, - NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg, - SECAlgorithmID **detached_digestalgs, SECItem **detached_digests); - -/* - * NSS_CMSMessage_Destroy - destroy a CMS message and all of its sub-pieces. - */ -extern void -NSS_CMSMessage_Destroy(NSSCMSMessage *cmsg); - -/* - * NSS_CMSMessage_Copy - return a copy of the given message. - * - * The copy may be virtual or may be real -- either way, the result needs - * to be passed to NSS_CMSMessage_Destroy later (as does the original). - */ -extern NSSCMSMessage * -NSS_CMSMessage_Copy(NSSCMSMessage *cmsg); - -/* - * NSS_CMSMessage_GetArena - return a pointer to the message's arena pool - */ -extern PLArenaPool * -NSS_CMSMessage_GetArena(NSSCMSMessage *cmsg); - -/* - * NSS_CMSMessage_GetContentInfo - return a pointer to the top level contentInfo - */ -extern NSSCMSContentInfo * -NSS_CMSMessage_GetContentInfo(NSSCMSMessage *cmsg); - -/* - * Return a pointer to the actual content. - * In the case of those types which are encrypted, this returns the *plain* content. - * In case of nested contentInfos, this descends and retrieves the innermost content. - */ -extern SECItem * -NSS_CMSMessage_GetContent(NSSCMSMessage *cmsg); - -/* - * NSS_CMSMessage_ContentLevelCount - count number of levels of CMS content objects in this message - * - * CMS data content objects do not count. - */ -extern int -NSS_CMSMessage_ContentLevelCount(NSSCMSMessage *cmsg); - -/* - * NSS_CMSMessage_ContentLevel - find content level #n - * - * CMS data content objects do not count. - */ -extern NSSCMSContentInfo * -NSS_CMSMessage_ContentLevel(NSSCMSMessage *cmsg, int n); - -/* - * NSS_CMSMessage_ContainsCertsOrCrls - see if message contains certs along the way - */ -extern PRBool -NSS_CMSMessage_ContainsCertsOrCrls(NSSCMSMessage *cmsg); - -/* - * NSS_CMSMessage_IsEncrypted - see if message contains a encrypted submessage - */ -extern PRBool -NSS_CMSMessage_IsEncrypted(NSSCMSMessage *cmsg); - -/* - * NSS_CMSMessage_IsSigned - see if message contains a signed submessage - * - * If the CMS message has a SignedData with a signature (not just a SignedData) - * return true; false otherwise. This can/should be called before calling - * VerifySignature, which will always indicate failure if no signature is - * present, but that does not mean there even was a signature! - * Note that the content itself can be empty (detached content was sent - * another way); it is the presence of the signature that matters. - */ -extern PRBool -NSS_CMSMessage_IsSigned(NSSCMSMessage *cmsg); - -/* - * NSS_CMSMessage_IsContentEmpty - see if content is empty - * - * returns PR_TRUE is innermost content length is < minLen - * XXX need the encrypted content length (why?) - */ -extern PRBool -NSS_CMSMessage_IsContentEmpty(NSSCMSMessage *cmsg, unsigned int minLen); - -/************************************************************************ - * cmscinfo.c - CMS contentInfo methods - ************************************************************************/ - -/* - * NSS_CMSContentInfo_Destroy - destroy a CMS contentInfo and all of its sub-pieces. - */ -extern void -NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo); - -/* - * NSS_CMSContentInfo_GetChildContentInfo - get content's contentInfo (if it exists) - */ -extern NSSCMSContentInfo * -NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo); - -/* - * NSS_CMSContentInfo_SetContent - set cinfo's content type & content to CMS object - */ -extern SECStatus -NSS_CMSContentInfo_SetContent(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECOidTag type, void *ptr); - -/* - * NSS_CMSContentInfo_SetContent_XXXX - typesafe wrappers for NSS_CMSContentInfo_SetType - * set cinfo's content type & content to CMS object - */ -extern SECStatus -NSS_CMSContentInfo_SetContent_Data(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECItem *data, PRBool detached); - -extern SECStatus -NSS_CMSContentInfo_SetContent_SignedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSSignedData *sigd); - -extern SECStatus -NSS_CMSContentInfo_SetContent_EnvelopedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEnvelopedData *envd); - -extern SECStatus -NSS_CMSContentInfo_SetContent_DigestedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSDigestedData *digd); - -extern SECStatus -NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEncryptedData *encd); - -/* - * NSS_CMSContentInfo_GetContent - get pointer to inner content - * - * needs to be casted... - */ -extern void * -NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo); - -/* - * NSS_CMSContentInfo_GetInnerContent - get pointer to innermost content - * - * this is typically only called by NSS_CMSMessage_GetContent() - */ -extern SECItem * -NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo); - -/* - * NSS_CMSContentInfo_GetContentType{Tag,OID} - find out (saving pointer to lookup result - * for future reference) and return the inner content type. - */ -extern SECOidTag -NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo); - -extern SECItem * -NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo); - -/* - * NSS_CMSContentInfo_GetContentEncAlgTag - find out (saving pointer to lookup result - * for future reference) and return the content encryption algorithm tag. - */ -extern SECOidTag -NSS_CMSContentInfo_GetContentEncAlgTag(NSSCMSContentInfo *cinfo); - -/* - * NSS_CMSContentInfo_GetContentEncAlg - find out and return the content encryption algorithm tag. - */ -extern SECAlgorithmID * -NSS_CMSContentInfo_GetContentEncAlg(NSSCMSContentInfo *cinfo); - -extern SECStatus -NSS_CMSContentInfo_SetContentEncAlg(PLArenaPool *poolp, NSSCMSContentInfo *cinfo, - SECOidTag bulkalgtag, SECItem *parameters, int keysize); - -extern SECStatus -NSS_CMSContentInfo_SetContentEncAlgID(PLArenaPool *poolp, NSSCMSContentInfo *cinfo, - SECAlgorithmID *algid, int keysize); - -extern void -NSS_CMSContentInfo_SetBulkKey(NSSCMSContentInfo *cinfo, PK11SymKey *bulkkey); - -extern PK11SymKey * -NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo *cinfo); - -extern int -NSS_CMSContentInfo_GetBulkKeySize(NSSCMSContentInfo *cinfo); - -/************************************************************************ - * cmsutil.c - CMS misc utility functions - ************************************************************************/ - -/* - * NSS_CMSArray_SortByDER - sort array of objects by objects' DER encoding - * - * make sure that the order of the objects guarantees valid DER (which must be - * in lexigraphically ascending order for a SET OF); if reordering is necessary it - * will be done in place (in objs). - */ -extern SECStatus -NSS_CMSArray_SortByDER(void **objs, const SEC_ASN1Template *objtemplate, void **objs2); - -/* - * NSS_CMSUtil_DERCompare - for use with NSS_CMSArray_Sort to - * sort arrays of SECItems containing DER - */ -extern int -NSS_CMSUtil_DERCompare(void *a, void *b); - -/* - * NSS_CMSAlgArray_GetIndexByAlgID - find a specific algorithm in an array of - * algorithms. - * - * algorithmArray - array of algorithm IDs - * algid - algorithmid of algorithm to pick - * - * Returns: - * An integer containing the index of the algorithm in the array or -1 if - * algorithm was not found. - */ -extern int -NSS_CMSAlgArray_GetIndexByAlgID(SECAlgorithmID **algorithmArray, SECAlgorithmID *algid); - -/* - * NSS_CMSAlgArray_GetIndexByAlgID - find a specific algorithm in an array of - * algorithms. - * - * algorithmArray - array of algorithm IDs - * algiddata - id of algorithm to pick - * - * Returns: - * An integer containing the index of the algorithm in the array or -1 if - * algorithm was not found. - */ -extern int -NSS_CMSAlgArray_GetIndexByAlgTag(SECAlgorithmID **algorithmArray, SECOidTag algtag); - -extern const SECHashObject * -NSS_CMSUtil_GetHashObjByAlgID(SECAlgorithmID *algid); - -/* - * XXX I would *really* like to not have to do this, but the current - * signing interface gives me little choice. - */ -extern SECOidTag -NSS_CMSUtil_MakeSignatureAlgorithm(SECOidTag hashalg, SECOidTag encalg); - -extern const SEC_ASN1Template * -NSS_CMSUtil_GetTemplateByTypeTag(SECOidTag type); - -extern size_t -NSS_CMSUtil_GetSizeByTypeTag(SECOidTag type); - -extern NSSCMSContentInfo * -NSS_CMSContent_GetContentInfo(void *msg, SECOidTag type); - -extern const char * -NSS_CMSUtil_VerificationStatusToString(NSSCMSVerificationStatus vs); - -/************************************************************************ - * cmssigdata.c - CMS signedData methods - ************************************************************************/ - -extern NSSCMSSignedData * -NSS_CMSSignedData_Create(NSSCMSMessage *cmsg); - -extern void -NSS_CMSSignedData_Destroy(NSSCMSSignedData *sigd); - -/* - * NSS_CMSSignedData_Encode_BeforeStart - do all the necessary things to a SignedData - * before start of encoding. - * - * In detail: - * - find out about the right value to put into sigd->version - * - come up with a list of digestAlgorithms (which should be the union of the algorithms - * in the signerinfos). - * If we happen to have a pre-set list of algorithms (and digest values!), we - * check if we have all the signerinfos' algorithms. If not, this is an error. - */ -extern SECStatus -NSS_CMSSignedData_Encode_BeforeStart(NSSCMSSignedData *sigd); - -extern SECStatus -NSS_CMSSignedData_Encode_BeforeData(NSSCMSSignedData *sigd); - -/* - * NSS_CMSSignedData_Encode_AfterData - do all the necessary things to a SignedData - * after all the encapsulated data was passed through the encoder. - * - * In detail: - * - create the signatures in all the SignerInfos - * - * Please note that nothing is done to the Certificates and CRLs in the message - this - * is entirely the responsibility of our callers. - */ -extern SECStatus -NSS_CMSSignedData_Encode_AfterData(NSSCMSSignedData *sigd); - -extern SECStatus -NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd); - -/* - * NSS_CMSSignedData_Decode_AfterData - do all the necessary things to a SignedData - * after all the encapsulated data was passed through the decoder. - */ -extern SECStatus -NSS_CMSSignedData_Decode_AfterData(NSSCMSSignedData *sigd); - -/* - * NSS_CMSSignedData_Decode_AfterEnd - do all the necessary things to a SignedData - * after all decoding is finished. - */ -extern SECStatus -NSS_CMSSignedData_Decode_AfterEnd(NSSCMSSignedData *sigd); - -/* - * NSS_CMSSignedData_GetSignerInfos - retrieve the SignedData's signer list - */ -extern NSSCMSSignerInfo ** -NSS_CMSSignedData_GetSignerInfos(NSSCMSSignedData *sigd); - -extern int -NSS_CMSSignedData_SignerInfoCount(NSSCMSSignedData *sigd); - -extern NSSCMSSignerInfo * -NSS_CMSSignedData_GetSignerInfo(NSSCMSSignedData *sigd, int i); - -/* - * NSS_CMSSignedData_GetDigestAlgs - retrieve the SignedData's digest algorithm list - */ -extern SECAlgorithmID ** -NSS_CMSSignedData_GetDigestAlgs(NSSCMSSignedData *sigd); - -/* - * NSS_CMSSignedData_GetContentInfo - return pointer to this signedData's contentinfo - */ -extern NSSCMSContentInfo * -NSS_CMSSignedData_GetContentInfo(NSSCMSSignedData *sigd); - -/* - * NSS_CMSSignedData_GetCertificateList - retrieve the SignedData's certificate list - */ -extern SECItem ** -NSS_CMSSignedData_GetCertificateList(NSSCMSSignedData *sigd); - -extern SECStatus -NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb, - SECCertUsage certusage, PRBool keepcerts); - -/* - * NSS_CMSSignedData_HasDigests - see if we have digests in place - */ -extern PRBool -NSS_CMSSignedData_HasDigests(NSSCMSSignedData *sigd); - -/* - * NSS_CMSSignedData_VerifySignerInfo - check a signature. - * - * The digests were either calculated during decoding (and are stored in the - * signedData itself) or set after decoding using NSS_CMSSignedData_SetDigests. - * - * The verification checks if the signing cert is valid and has a trusted chain - * for the purpose specified by "certusage". - */ -extern SECStatus -NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i, CERTCertDBHandle *certdb, - SECCertUsage certusage); - -/* - * NSS_CMSSignedData_VerifyCertsOnly - verify the certs in a certs-only message -*/ -extern SECStatus -NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd, - CERTCertDBHandle *certdb, - SECCertUsage usage); - -extern SECStatus -NSS_CMSSignedData_AddCertList(NSSCMSSignedData *sigd, CERTCertificateList *certlist); - -/* - * NSS_CMSSignedData_AddCertChain - add cert and its entire chain to the set of certs - */ -extern SECStatus -NSS_CMSSignedData_AddCertChain(NSSCMSSignedData *sigd, CERTCertificate *cert); - -extern SECStatus -NSS_CMSSignedData_AddCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert); - -extern PRBool -NSS_CMSSignedData_ContainsCertsOrCrls(NSSCMSSignedData *sigd); - -extern SECStatus -NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd, - NSSCMSSignerInfo *signerinfo); - -extern SECStatus -NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd, - SECAlgorithmID **digestalgs, - SECItem **digests); - -extern SECStatus -NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd, - SECOidTag digestalgtag, - SECItem *digestdata); - -extern SECStatus -NSS_CMSSignedData_AddDigest(PRArenaPool *poolp, - NSSCMSSignedData *sigd, - SECOidTag digestalgtag, - SECItem *digest); - -extern SECItem * -NSS_CMSSignedData_GetDigestValue(NSSCMSSignedData *sigd, SECOidTag digestalgtag); - -/* - * NSS_CMSSignedData_CreateCertsOnly - create a certs-only SignedData. - * - * cert - base certificates that will be included - * include_chain - if true, include the complete cert chain for cert - * - * More certs and chains can be added via AddCertificate and AddCertChain. - * - * An error results in a return value of NULL and an error set. - */ -extern NSSCMSSignedData * -NSS_CMSSignedData_CreateCertsOnly(NSSCMSMessage *cmsg, CERTCertificate *cert, PRBool include_chain); - -/************************************************************************ - * cmssiginfo.c - signerinfo methods - ************************************************************************/ - -extern NSSCMSSignerInfo * -NSS_CMSSignerInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert, SECOidTag digestalgtag); -extern NSSCMSSignerInfo * -NSS_CMSSignerInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg, SECItem *subjKeyID, SECKEYPublicKey *pubKey, SECKEYPrivateKey *signingKey, SECOidTag digestalgtag); - -/* - * NSS_CMSSignerInfo_Destroy - destroy a SignerInfo data structure - */ -extern void -NSS_CMSSignerInfo_Destroy(NSSCMSSignerInfo *si); - -/* - * NSS_CMSSignerInfo_Sign - sign something - * - */ -extern SECStatus -NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *contentType); - -extern SECStatus -NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb, - SECCertUsage certusage); - -/* - * NSS_CMSSignerInfo_Verify - verify the signature of a single SignerInfo - * - * Just verifies the signature. The assumption is that verification of the certificate - * is done already. - */ -extern SECStatus -NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *contentType); - -extern NSSCMSVerificationStatus -NSS_CMSSignerInfo_GetVerificationStatus(NSSCMSSignerInfo *signerinfo); - -extern SECOidData * -NSS_CMSSignerInfo_GetDigestAlg(NSSCMSSignerInfo *signerinfo); - -extern SECOidTag -NSS_CMSSignerInfo_GetDigestAlgTag(NSSCMSSignerInfo *signerinfo); - -extern int -NSS_CMSSignerInfo_GetVersion(NSSCMSSignerInfo *signerinfo); - -extern CERTCertificateList * -NSS_CMSSignerInfo_GetCertList(NSSCMSSignerInfo *signerinfo); - -/* - * NSS_CMSSignerInfo_GetSigningTime - return the signing time, - * in UTCTime format, of a CMS signerInfo. - * - * sinfo - signerInfo data for this signer - * - * Returns a pointer to XXXX (what?) - * A return value of NULL is an error. - */ -extern SECStatus -NSS_CMSSignerInfo_GetSigningTime(NSSCMSSignerInfo *sinfo, PRTime *stime); - -/* - * Return the signing cert of a CMS signerInfo. - * - * the certs in the enclosing SignedData must have been imported already - */ -extern CERTCertificate * -NSS_CMSSignerInfo_GetSigningCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb); - -/* - * NSS_CMSSignerInfo_GetSignerCommonName - return the common name of the signer - * - * sinfo - signerInfo data for this signer - * - * Returns a pointer to allocated memory, which must be freed with PORT_Free. - * A return value of NULL is an error. - */ -extern char * -NSS_CMSSignerInfo_GetSignerCommonName(NSSCMSSignerInfo *sinfo); - -/* - * NSS_CMSSignerInfo_GetSignerEmailAddress - return the common name of the signer - * - * sinfo - signerInfo data for this signer - * - * Returns a pointer to allocated memory, which must be freed. - * A return value of NULL is an error. - */ -extern char * -NSS_CMSSignerInfo_GetSignerEmailAddress(NSSCMSSignerInfo *sinfo); - -/* - * NSS_CMSSignerInfo_AddAuthAttr - add an attribute to the - * authenticated (i.e. signed) attributes of "signerinfo". - */ -extern SECStatus -NSS_CMSSignerInfo_AddAuthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr); - -/* - * NSS_CMSSignerInfo_AddUnauthAttr - add an attribute to the - * unauthenticated attributes of "signerinfo". - */ -extern SECStatus -NSS_CMSSignerInfo_AddUnauthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr); - -/* - * NSS_CMSSignerInfo_AddSigningTime - add the signing time to the - * authenticated (i.e. signed) attributes of "signerinfo". - * - * This is expected to be included in outgoing signed - * messages for email (S/MIME) but is likely useful in other situations. - * - * This should only be added once; a second call will do nothing. - * - * XXX This will probably just shove the current time into "signerinfo" - * but it will not actually get signed until the entire item is - * processed for encoding. Is this (expected to be small) delay okay? - */ -extern SECStatus -NSS_CMSSignerInfo_AddSigningTime(NSSCMSSignerInfo *signerinfo, PRTime t); - -/* - * NSS_CMSSignerInfo_AddSMIMECaps - add a SMIMECapabilities attribute to the - * authenticated (i.e. signed) attributes of "signerinfo". - * - * This is expected to be included in outgoing signed - * messages for email (S/MIME). - */ -extern SECStatus -NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo); - -/* - * NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the - * authenticated (i.e. signed) attributes of "signerinfo". - * - * This is expected to be included in outgoing signed messages for email (S/MIME). - */ -SECStatus -NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb); - -/* - * NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the - * authenticated (i.e. signed) attributes of "signerinfo", using the OID prefered by Microsoft. - * - * This is expected to be included in outgoing signed messages for email (S/MIME), - * if compatibility with Microsoft mail clients is wanted. - */ -SECStatus -NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb); - -/* - * NSS_CMSSignerInfo_AddCounterSignature - countersign a signerinfo - */ -extern SECStatus -NSS_CMSSignerInfo_AddCounterSignature(NSSCMSSignerInfo *signerinfo, - SECOidTag digestalg, CERTCertificate signingcert); - -/* - * XXXX the following needs to be done in the S/MIME layer code - * after signature of a signerinfo is verified - */ -extern SECStatus -NSS_SMIMESignerInfo_SaveSMIMEProfile(NSSCMSSignerInfo *signerinfo); - -/* - * NSS_CMSSignerInfo_IncludeCerts - set cert chain inclusion mode for this signer - */ -extern SECStatus -NSS_CMSSignerInfo_IncludeCerts(NSSCMSSignerInfo *signerinfo, NSSCMSCertChainMode cm, SECCertUsage usage); - -/************************************************************************ - * cmsenvdata.c - CMS envelopedData methods - ************************************************************************/ - -/* - * NSS_CMSEnvelopedData_Create - create an enveloped data message - */ -extern NSSCMSEnvelopedData * -NSS_CMSEnvelopedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize); - -/* - * NSS_CMSEnvelopedData_Destroy - destroy an enveloped data message - */ -extern void -NSS_CMSEnvelopedData_Destroy(NSSCMSEnvelopedData *edp); - -/* - * NSS_CMSEnvelopedData_GetContentInfo - return pointer to this envelopedData's contentinfo - */ -extern NSSCMSContentInfo * -NSS_CMSEnvelopedData_GetContentInfo(NSSCMSEnvelopedData *envd); - -/* - * NSS_CMSEnvelopedData_AddRecipient - add a recipientinfo to the enveloped data msg - * - * rip must be created on the same pool as edp - this is not enforced, though. - */ -extern SECStatus -NSS_CMSEnvelopedData_AddRecipient(NSSCMSEnvelopedData *edp, NSSCMSRecipientInfo *rip); - -/* - * NSS_CMSEnvelopedData_Encode_BeforeStart - prepare this envelopedData for encoding - * - * at this point, we need - * - recipientinfos set up with recipient's certificates - * - a content encryption algorithm (if none, 3DES will be used) - * - * this function will generate a random content encryption key (aka bulk key), - * initialize the recipientinfos with certificate identification and wrap the bulk key - * using the proper algorithm for every certificiate. - * it will finally set the bulk algorithm and key so that the encode step can find it. - */ -extern SECStatus -NSS_CMSEnvelopedData_Encode_BeforeStart(NSSCMSEnvelopedData *envd); - -/* - * NSS_CMSEnvelopedData_Encode_BeforeData - set up encryption - */ -extern SECStatus -NSS_CMSEnvelopedData_Encode_BeforeData(NSSCMSEnvelopedData *envd); - -/* - * NSS_CMSEnvelopedData_Encode_AfterData - finalize this envelopedData for encoding - */ -extern SECStatus -NSS_CMSEnvelopedData_Encode_AfterData(NSSCMSEnvelopedData *envd); - -/* - * NSS_CMSEnvelopedData_Decode_BeforeData - find our recipientinfo, - * derive bulk key & set up our contentinfo - */ -extern SECStatus -NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd); - -/* - * NSS_CMSEnvelopedData_Decode_AfterData - finish decrypting this envelopedData's content - */ -extern SECStatus -NSS_CMSEnvelopedData_Decode_AfterData(NSSCMSEnvelopedData *envd); - -/* - * NSS_CMSEnvelopedData_Decode_AfterEnd - finish decoding this envelopedData - */ -extern SECStatus -NSS_CMSEnvelopedData_Decode_AfterEnd(NSSCMSEnvelopedData *envd); - - -/************************************************************************ - * cmsrecinfo.c - CMS recipientInfo methods - ************************************************************************/ - -/* - * NSS_CMSRecipientInfo_Create - create a recipientinfo - * - * we currently do not create KeyAgreement recipientinfos with multiple recipientEncryptedKeys - * the certificate is supposed to have been verified by the caller - */ -extern NSSCMSRecipientInfo * -NSS_CMSRecipientInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert); - -extern NSSCMSRecipientInfo * -NSS_CMSRecipientInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg, - SECItem *subjKeyID, - SECKEYPublicKey *pubKey); - -extern NSSCMSRecipientInfo * -NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert(NSSCMSMessage *cmsg, - CERTCertificate *cert); - -/* - * NSS_CMSRecipientInfo_CreateNew - create a blank recipientinfo for - * applications which want to encode their own CMS structures and - * key exchange types. - */ -extern NSSCMSRecipientInfo * -NSS_CMSRecipientInfo_CreateNew(void* pwfn_arg); - -/* - * NSS_CMSRecipientInfo_CreateFromDER - create a recipientinfo from partially - * decoded DER data for applications which want to encode their own CMS - * structures and key exchange types. - */ -extern NSSCMSRecipientInfo * -NSS_CMSRecipientInfo_CreateFromDER(SECItem* input, void* pwfn_arg); - -extern void -NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri); - -/* - * NSS_CMSRecipientInfo_GetCertAndKey - retrieve the cert and key from the - * recipientInfo struct. If retcert or retkey are NULL, the cert or - * key (respectively) would not be returned). This function is a no-op if both - * retcert and retkey are NULL. Caller inherits ownership of the cert and key - * he requested (and is responsible to free them). - */ -SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri, - CERTCertificate** retcert, SECKEYPrivateKey** retkey); - -extern int -NSS_CMSRecipientInfo_GetVersion(NSSCMSRecipientInfo *ri); - -extern SECItem * -NSS_CMSRecipientInfo_GetEncryptedKey(NSSCMSRecipientInfo *ri, int subIndex); - -/* - * NSS_CMSRecipientInfo_Encode - encode an NSS_CMSRecipientInfo as ASN.1 - */ -SECStatus NSS_CMSRecipientInfo_Encode(PRArenaPool* poolp, - const NSSCMSRecipientInfo *src, - SECItem* returned); - -extern SECOidTag -NSS_CMSRecipientInfo_GetKeyEncryptionAlgorithmTag(NSSCMSRecipientInfo *ri); - -extern SECStatus -NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey, SECOidTag bulkalgtag); - -extern PK11SymKey * -NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex, - CERTCertificate *cert, SECKEYPrivateKey *privkey, SECOidTag bulkalgtag); - -/************************************************************************ - * cmsencdata.c - CMS encryptedData methods - ************************************************************************/ -/* - * NSS_CMSEncryptedData_Create - create an empty encryptedData object. - * - * "algorithm" specifies the bulk encryption algorithm to use. - * "keysize" is the key size. - * - * An error results in a return value of NULL and an error set. - * (Retrieve specific errors via PORT_GetError()/XP_GetError().) - */ -extern NSSCMSEncryptedData * -NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize); - -/* - * NSS_CMSEncryptedData_Destroy - destroy an encryptedData object - */ -extern void -NSS_CMSEncryptedData_Destroy(NSSCMSEncryptedData *encd); - -/* - * NSS_CMSEncryptedData_GetContentInfo - return pointer to encryptedData object's contentInfo - */ -extern NSSCMSContentInfo * -NSS_CMSEncryptedData_GetContentInfo(NSSCMSEncryptedData *encd); - -/* - * NSS_CMSEncryptedData_Encode_BeforeStart - do all the necessary things to a EncryptedData - * before encoding begins. - * - * In particular: - * - set the correct version value. - * - get the encryption key - */ -extern SECStatus -NSS_CMSEncryptedData_Encode_BeforeStart(NSSCMSEncryptedData *encd); - -/* - * NSS_CMSEncryptedData_Encode_BeforeData - set up encryption - */ -extern SECStatus -NSS_CMSEncryptedData_Encode_BeforeData(NSSCMSEncryptedData *encd); - -/* - * NSS_CMSEncryptedData_Encode_AfterData - finalize this encryptedData for encoding - */ -extern SECStatus -NSS_CMSEncryptedData_Encode_AfterData(NSSCMSEncryptedData *encd); - -/* - * NSS_CMSEncryptedData_Decode_BeforeData - find bulk key & set up decryption - */ -extern SECStatus -NSS_CMSEncryptedData_Decode_BeforeData(NSSCMSEncryptedData *encd); - -/* - * NSS_CMSEncryptedData_Decode_AfterData - finish decrypting this encryptedData's content - */ -extern SECStatus -NSS_CMSEncryptedData_Decode_AfterData(NSSCMSEncryptedData *encd); - -/* - * NSS_CMSEncryptedData_Decode_AfterEnd - finish decoding this encryptedData - */ -extern SECStatus -NSS_CMSEncryptedData_Decode_AfterEnd(NSSCMSEncryptedData *encd); - -/************************************************************************ - * cmsdigdata.c - CMS encryptedData methods - ************************************************************************/ -/* - * NSS_CMSDigestedData_Create - create a digestedData object (presumably for encoding) - * - * version will be set by NSS_CMSDigestedData_Encode_BeforeStart - * digestAlg is passed as parameter - * contentInfo must be filled by the user - * digest will be calculated while encoding - */ -extern NSSCMSDigestedData * -NSS_CMSDigestedData_Create(NSSCMSMessage *cmsg, SECAlgorithmID *digestalg); - -/* - * NSS_CMSDigestedData_Destroy - destroy a digestedData object - */ -extern void -NSS_CMSDigestedData_Destroy(NSSCMSDigestedData *digd); - -/* - * NSS_CMSDigestedData_GetContentInfo - return pointer to digestedData object's contentInfo - */ -extern NSSCMSContentInfo * -NSS_CMSDigestedData_GetContentInfo(NSSCMSDigestedData *digd); - -/* - * NSS_CMSDigestedData_Encode_BeforeStart - do all the necessary things to a DigestedData - * before encoding begins. - * - * In particular: - * - set the right version number. The contentInfo's content type must be set up already. - */ -extern SECStatus -NSS_CMSDigestedData_Encode_BeforeStart(NSSCMSDigestedData *digd); - -/* - * NSS_CMSDigestedData_Encode_BeforeData - do all the necessary things to a DigestedData - * before the encapsulated data is passed through the encoder. - * - * In detail: - * - set up the digests if necessary - */ -extern SECStatus -NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData *digd); - -/* - * NSS_CMSDigestedData_Encode_AfterData - do all the necessary things to a DigestedData - * after all the encapsulated data was passed through the encoder. - * - * In detail: - * - finish the digests - */ -extern SECStatus -NSS_CMSDigestedData_Encode_AfterData(NSSCMSDigestedData *digd); - -/* - * NSS_CMSDigestedData_Decode_BeforeData - do all the necessary things to a DigestedData - * before the encapsulated data is passed through the encoder. - * - * In detail: - * - set up the digests if necessary - */ -extern SECStatus -NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData *digd); - -/* - * NSS_CMSDigestedData_Decode_AfterData - do all the necessary things to a DigestedData - * after all the encapsulated data was passed through the encoder. - * - * In detail: - * - finish the digests - */ -extern SECStatus -NSS_CMSDigestedData_Decode_AfterData(NSSCMSDigestedData *digd); - -/* - * NSS_CMSDigestedData_Decode_AfterEnd - finalize a digestedData. - * - * In detail: - * - check the digests for equality - */ -extern SECStatus -NSS_CMSDigestedData_Decode_AfterEnd(NSSCMSDigestedData *digd); - -/************************************************************************ - * cmsdigest.c - digestion routines - ************************************************************************/ - -/* - * NSS_CMSDigestContext_StartMultiple - start digest calculation using all the - * digest algorithms in "digestalgs" in parallel. - */ -extern NSSCMSDigestContext * -NSS_CMSDigestContext_StartMultiple(SECAlgorithmID **digestalgs); - -/* - * NSS_CMSDigestContext_StartSingle - same as NSS_CMSDigestContext_StartMultiple, but - * only one algorithm. - */ -extern NSSCMSDigestContext * -NSS_CMSDigestContext_StartSingle(SECAlgorithmID *digestalg); - -/* - * NSS_CMSDigestContext_Update - feed more data into the digest machine - */ -extern void -NSS_CMSDigestContext_Update(NSSCMSDigestContext *cmsdigcx, const unsigned char *data, int len); - -/* - * NSS_CMSDigestContext_Cancel - cancel digesting operation - */ -extern void -NSS_CMSDigestContext_Cancel(NSSCMSDigestContext *cmsdigcx); - -/* - * NSS_CMSDigestContext_FinishMultiple - finish the digests and put them - * into an array of SECItems (allocated on poolp) - */ -extern SECStatus -NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx, PLArenaPool *poolp, - SECItem ***digestsp); - -/* - * NSS_CMSDigestContext_FinishSingle - same as NSS_CMSDigestContext_FinishMultiple, - * but for one digest. - */ -extern SECStatus -NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx, PLArenaPool *poolp, - SECItem *digest); - -/************************************************************************ - * - ************************************************************************/ - -/* shortcuts for basic use */ - -/* - * NSS_CMSDEREncode - DER Encode a CMS message, with input being - * the plaintext message and derOut being the output, - * stored in arena's pool. - */ -extern SECStatus -NSS_CMSDEREncode(NSSCMSMessage *cmsg, SECItem *input, SECItem *derOut, - PLArenaPool *arena); - - -/************************************************************************/ -SEC_END_PROTOS - -#endif /* _CMS_H_ */ diff --git a/security/nss/lib/smime/cmsarray.c b/security/nss/lib/smime/cmsarray.c deleted file mode 100644 index 7f331c82a..000000000 --- a/security/nss/lib/smime/cmsarray.c +++ /dev/null @@ -1,219 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS array functions. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "secerr.h" - -/* - * ARRAY FUNCTIONS - * - * In NSS, arrays are rather primitive arrays of pointers. - * Makes it easy to walk the array, but hard to count elements - * and manage the storage. - * - * This is a feeble attempt to encapsulate the functionality - * and get rid of hundreds of lines of similar code - */ - -/* - * NSS_CMSArray_Alloc - allocate an array in an arena - * - * This allocates space for the array of pointers - */ -void ** -NSS_CMSArray_Alloc(PRArenaPool *poolp, int n) -{ - return (void **)PORT_ArenaZAlloc(poolp, n * sizeof(void *)); -} - -/* - * NSS_CMSArray_Add - add an element to the end of an array - * - * The array of pointers is either created (if array was empty before) or grown. - */ -SECStatus -NSS_CMSArray_Add(PRArenaPool *poolp, void ***array, void *obj) -{ - void **p; - int n; - void **dest; - - PORT_Assert(array != NULL); - if (array == NULL) - return SECFailure; - - if (*array == NULL) { - dest = (void **)PORT_ArenaAlloc(poolp, 2 * sizeof(void *)); - n = 0; - } else { - n = 0; p = *array; - while (*p++) - n++; - dest = (void **)PORT_ArenaGrow (poolp, - *array, - (n + 1) * sizeof(void *), - (n + 2) * sizeof(void *)); - } - - if (dest == NULL) - return SECFailure; - - dest[n] = obj; - dest[n+1] = NULL; - *array = dest; - return SECSuccess; -} - -/* - * NSS_CMSArray_IsEmpty - check if array is empty - */ -PRBool -NSS_CMSArray_IsEmpty(void **array) -{ - return (array == NULL || array[0] == NULL); -} - -/* - * NSS_CMSArray_Count - count number of elements in array - */ -int -NSS_CMSArray_Count(void **array) -{ - int n = 0; - - if (array == NULL) - return 0; - - while (*array++ != NULL) - n++; - - return n; -} - -/* - * NSS_CMSArray_Sort - sort an array in place - * - * If "secondary" or "tertiary are not NULL, it must be arrays with the same - * number of elements as "primary". The same reordering will get applied to it. - * - * "compare" is a function that returns - * < 0 when the first element is less than the second - * = 0 when the first element is equal to the second - * > 0 when the first element is greater than the second - * to acheive ascending ordering. - */ -void -NSS_CMSArray_Sort(void **primary, int (*compare)(void *,void *), void **secondary, void **tertiary) -{ - int n, i, limit, lastxchg; - void *tmp; - - n = NSS_CMSArray_Count(primary); - - PORT_Assert(secondary == NULL || NSS_CMSArray_Count(secondary) == n); - PORT_Assert(tertiary == NULL || NSS_CMSArray_Count(tertiary) == n); - - if (n <= 1) /* ordering is fine */ - return; - - /* yes, ladies and gentlemen, it's BUBBLE SORT TIME! */ - limit = n - 1; - while (1) { - lastxchg = 0; - for (i = 0; i < limit; i++) { - if ((*compare)(primary[i], primary[i+1]) > 0) { - /* exchange the neighbours */ - tmp = primary[i+1]; - primary[i+1] = primary[i]; - primary[i] = tmp; - if (secondary) { /* secondary array? */ - tmp = secondary[i+1]; /* exchange there as well */ - secondary[i+1] = secondary[i]; - secondary[i] = tmp; - } - if (tertiary) { /* tertiary array? */ - tmp = tertiary[i+1]; /* exchange there as well */ - tertiary[i+1] = tertiary[i]; - tertiary[i] = tmp; - } - lastxchg = i+1; /* index of the last element bubbled up */ - } - } - if (lastxchg == 0) /* no exchanges, so array is sorted */ - break; /* we're done */ - limit = lastxchg; /* array is sorted up to [limit] */ - } -} - -#if 0 - -/* array iterator stuff... not used */ - -typedef void **NSSCMSArrayIterator; - -/* iterator */ -NSSCMSArrayIterator -NSS_CMSArray_First(void **array) -{ - if (array == NULL || array[0] == NULL) - return NULL; - return (NSSCMSArrayIterator)&(array[0]); -} - -void * -NSS_CMSArray_Obj(NSSCMSArrayIterator iter) -{ - void **p = (void **)iter; - - return *iter; /* which is NULL if we are at the end of the array */ -} - -NSSCMSArrayIterator -NSS_CMSArray_Next(NSSCMSArrayIterator iter) -{ - void **p = (void **)iter; - - return (NSSCMSArrayIterator)(p + 1); -} - -#endif diff --git a/security/nss/lib/smime/cmsasn1.c b/security/nss/lib/smime/cmsasn1.c deleted file mode 100644 index 93d206e90..000000000 --- a/security/nss/lib/smime/cmsasn1.c +++ /dev/null @@ -1,578 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS ASN.1 templates - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "cert.h" -#include "key.h" -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "prtime.h" -#include "secerr.h" - - -extern const SEC_ASN1Template nss_cms_set_of_attribute_template[]; - -SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate) -SEC_ASN1_MKSUB(CERT_SetOfSignedCrlTemplate) -SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) -SEC_ASN1_MKSUB(SEC_BitStringTemplate) -SEC_ASN1_MKSUB(SEC_OctetStringTemplate) -SEC_ASN1_MKSUB(SEC_PointerToOctetStringTemplate) -SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate) - -/* ----------------------------------------------------------------------------- - * MESSAGE - * (uses NSSCMSContentInfo) - */ - -/* forward declaration */ -static const SEC_ASN1Template * -nss_cms_choose_content_template(void *src_or_dest, PRBool encoding); - -static const SEC_ASN1TemplateChooserPtr nss_cms_chooser - = nss_cms_choose_content_template; - -const SEC_ASN1Template NSSCMSMessageTemplate[] = { - { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, - 0, NULL, sizeof(NSSCMSMessage) }, - { SEC_ASN1_OBJECT_ID, - offsetof(NSSCMSMessage,contentInfo.contentType) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM - | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(NSSCMSMessage,contentInfo.content), - &nss_cms_chooser }, - { 0 } -}; - -static const SEC_ASN1Template NSS_PointerToCMSMessageTemplate[] = { - { SEC_ASN1_POINTER, 0, NSSCMSMessageTemplate } -}; - -/* ----------------------------------------------------------------------------- - * ENCAPSULATED & ENCRYPTED CONTENTINFO - * (both use a NSSCMSContentInfo) - */ -static const SEC_ASN1Template NSSCMSEncapsulatedContentInfoTemplate[] = { - { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, - 0, NULL, sizeof(NSSCMSContentInfo) }, - { SEC_ASN1_OBJECT_ID, - offsetof(NSSCMSContentInfo,contentType) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_MAY_STREAM | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, - offsetof(NSSCMSContentInfo,rawContent), - SEC_ASN1_SUB(SEC_PointerToOctetStringTemplate) }, - { 0 } -}; - -static const SEC_ASN1Template NSSCMSEncryptedContentInfoTemplate[] = { - { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, - 0, NULL, sizeof(NSSCMSContentInfo) }, - { SEC_ASN1_OBJECT_ID, - offsetof(NSSCMSContentInfo,contentType) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSCMSContentInfo,contentEncAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_MAY_STREAM | - SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, - offsetof(NSSCMSContentInfo,rawContent), - SEC_ASN1_SUB(SEC_OctetStringTemplate) }, - { 0 } -}; - -/* ----------------------------------------------------------------------------- - * SIGNED DATA - */ - -const SEC_ASN1Template NSSCMSSignerInfoTemplate[]; - -const SEC_ASN1Template NSSCMSSignedDataTemplate[] = { - { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, - 0, NULL, sizeof(NSSCMSSignedData) }, - { SEC_ASN1_INTEGER, - offsetof(NSSCMSSignedData,version) }, - { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, - offsetof(NSSCMSSignedData,digestAlgorithms), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_INLINE, - offsetof(NSSCMSSignedData,contentInfo), - NSSCMSEncapsulatedContentInfoTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 0, - offsetof(NSSCMSSignedData,rawCerts), - SEC_ASN1_SUB(SEC_SetOfAnyTemplate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 1, - offsetof(NSSCMSSignedData,crls), - SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) }, - { SEC_ASN1_SET_OF, - offsetof(NSSCMSSignedData,signerInfos), - NSSCMSSignerInfoTemplate }, - { 0 } -}; - -const SEC_ASN1Template NSS_PointerToCMSSignedDataTemplate[] = { - { SEC_ASN1_POINTER, 0, NSSCMSSignedDataTemplate } -}; - -/* ----------------------------------------------------------------------------- - * signeridentifier - */ - -static const SEC_ASN1Template NSSCMSSignerIdentifierTemplate[] = { - { SEC_ASN1_CHOICE, - offsetof(NSSCMSSignerIdentifier,identifierType), NULL, - sizeof(NSSCMSSignerIdentifier) }, - { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, - offsetof(NSSCMSSignerIdentifier,id.subjectKeyID), - SEC_ASN1_SUB(SEC_OctetStringTemplate) , - NSSCMSRecipientID_SubjectKeyID }, - { SEC_ASN1_POINTER | SEC_ASN1_XTRN, - offsetof(NSSCMSSignerIdentifier,id.issuerAndSN), - SEC_ASN1_SUB(CERT_IssuerAndSNTemplate), - NSSCMSRecipientID_IssuerSN }, - { 0 } -}; - -/* ----------------------------------------------------------------------------- - * signerinfo - */ - -const SEC_ASN1Template NSSCMSSignerInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSSignerInfo) }, - { SEC_ASN1_INTEGER, - offsetof(NSSCMSSignerInfo,version) }, - { SEC_ASN1_INLINE, - offsetof(NSSCMSSignerInfo,signerIdentifier), - NSSCMSSignerIdentifierTemplate }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSCMSSignerInfo,digestAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(NSSCMSSignerInfo,authAttr), - nss_cms_set_of_attribute_template }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSCMSSignerInfo,digestEncAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSSignerInfo,encDigest) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(NSSCMSSignerInfo,unAuthAttr), - nss_cms_set_of_attribute_template }, - { 0 } -}; - -/* ----------------------------------------------------------------------------- - * ENVELOPED DATA - */ - -static const SEC_ASN1Template NSSCMSOriginatorInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSOriginatorInfo) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 0, - offsetof(NSSCMSOriginatorInfo,rawCerts), - SEC_ASN1_SUB(SEC_SetOfAnyTemplate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 1, - offsetof(NSSCMSOriginatorInfo,crls), - SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) }, - { 0 } -}; - -const SEC_ASN1Template NSSCMSRecipientInfoTemplate[]; - -const SEC_ASN1Template NSSCMSEnvelopedDataTemplate[] = { - { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, - 0, NULL, sizeof(NSSCMSEnvelopedData) }, - { SEC_ASN1_INTEGER, - offsetof(NSSCMSEnvelopedData,version) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(NSSCMSEnvelopedData,originatorInfo), - NSSCMSOriginatorInfoTemplate }, - { SEC_ASN1_SET_OF, - offsetof(NSSCMSEnvelopedData,recipientInfos), - NSSCMSRecipientInfoTemplate }, - { SEC_ASN1_INLINE, - offsetof(NSSCMSEnvelopedData,contentInfo), - NSSCMSEncryptedContentInfoTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(NSSCMSEnvelopedData,unprotectedAttr), - nss_cms_set_of_attribute_template }, - { 0 } -}; - -const SEC_ASN1Template NSS_PointerToCMSEnvelopedDataTemplate[] = { - { SEC_ASN1_POINTER, 0, NSSCMSEnvelopedDataTemplate } -}; - -/* here come the 15 gazillion templates for all the v3 varieties of RecipientInfo */ - -/* ----------------------------------------------------------------------------- - * key transport recipient info - */ - -static const SEC_ASN1Template NSSCMSRecipientIdentifierTemplate[] = { - { SEC_ASN1_CHOICE, - offsetof(NSSCMSRecipientIdentifier,identifierType), NULL, - sizeof(NSSCMSRecipientIdentifier) }, - { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 0, - offsetof(NSSCMSRecipientIdentifier,id.subjectKeyID), - SEC_ASN1_SUB(SEC_PointerToOctetStringTemplate) , - NSSCMSRecipientID_SubjectKeyID }, - { SEC_ASN1_POINTER | SEC_ASN1_XTRN, - offsetof(NSSCMSRecipientIdentifier,id.issuerAndSN), - SEC_ASN1_SUB(CERT_IssuerAndSNTemplate), - NSSCMSRecipientID_IssuerSN }, - { 0 } -}; - - -static const SEC_ASN1Template NSSCMSKeyTransRecipientInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSKeyTransRecipientInfo) }, - { SEC_ASN1_INTEGER, - offsetof(NSSCMSKeyTransRecipientInfo,version) }, - { SEC_ASN1_INLINE, - offsetof(NSSCMSKeyTransRecipientInfo,recipientIdentifier), - NSSCMSRecipientIdentifierTemplate }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSCMSKeyTransRecipientInfo,keyEncAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSKeyTransRecipientInfo,encKey) }, - { 0 } -}; - -/* ----------------------------------------------------------------------------- - * key agreement recipient info - */ - -static const SEC_ASN1Template NSSCMSOriginatorPublicKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSOriginatorPublicKey) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSCMSOriginatorPublicKey,algorithmIdentifier), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSCMSOriginatorPublicKey,publicKey), - SEC_ASN1_SUB(SEC_BitStringTemplate) }, - { 0 } -}; - - -static const SEC_ASN1Template NSSCMSOriginatorIdentifierOrKeyTemplate[] = { - { SEC_ASN1_CHOICE, - offsetof(NSSCMSOriginatorIdentifierOrKey,identifierType), NULL, - sizeof(NSSCMSOriginatorIdentifierOrKey) }, - { SEC_ASN1_POINTER | SEC_ASN1_XTRN, - offsetof(NSSCMSOriginatorIdentifierOrKey,id.issuerAndSN), - SEC_ASN1_SUB(CERT_IssuerAndSNTemplate), - NSSCMSOriginatorIDOrKey_IssuerSN }, - { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 1, - offsetof(NSSCMSOriginatorIdentifierOrKey,id.subjectKeyID), - SEC_ASN1_SUB(SEC_PointerToOctetStringTemplate) , - NSSCMSOriginatorIDOrKey_SubjectKeyID }, - { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2, - offsetof(NSSCMSOriginatorIdentifierOrKey,id.originatorPublicKey), - NSSCMSOriginatorPublicKeyTemplate, - NSSCMSOriginatorIDOrKey_OriginatorPublicKey }, - { 0 } -}; - -const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSRecipientKeyIdentifier) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSRecipientKeyIdentifier,subjectKeyIdentifier) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSRecipientKeyIdentifier,date) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSRecipientKeyIdentifier,other) }, - { 0 } -}; - - -static const SEC_ASN1Template NSSCMSKeyAgreeRecipientIdentifierTemplate[] = { - { SEC_ASN1_CHOICE, - offsetof(NSSCMSKeyAgreeRecipientIdentifier,identifierType), NULL, - sizeof(NSSCMSKeyAgreeRecipientIdentifier) }, - { SEC_ASN1_POINTER | SEC_ASN1_XTRN, - offsetof(NSSCMSKeyAgreeRecipientIdentifier,id.issuerAndSN), - SEC_ASN1_SUB(CERT_IssuerAndSNTemplate), - NSSCMSKeyAgreeRecipientID_IssuerSN }, - { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(NSSCMSKeyAgreeRecipientIdentifier,id.recipientKeyIdentifier), - NSSCMSRecipientKeyIdentifierTemplate, - NSSCMSKeyAgreeRecipientID_RKeyID }, - { 0 } -}; - -static const SEC_ASN1Template NSSCMSRecipientEncryptedKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSRecipientEncryptedKey) }, - { SEC_ASN1_INLINE, - offsetof(NSSCMSRecipientEncryptedKey,recipientIdentifier), - NSSCMSKeyAgreeRecipientIdentifierTemplate }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSCMSRecipientEncryptedKey,encKey), - SEC_ASN1_SUB(SEC_BitStringTemplate) }, - { 0 } -}; - -static const SEC_ASN1Template NSSCMSKeyAgreeRecipientInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSKeyAgreeRecipientInfo) }, - { SEC_ASN1_INTEGER, - offsetof(NSSCMSKeyAgreeRecipientInfo,version) }, - { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(NSSCMSKeyAgreeRecipientInfo,originatorIdentifierOrKey), - NSSCMSOriginatorIdentifierOrKeyTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, - offsetof(NSSCMSKeyAgreeRecipientInfo,ukm), - SEC_ASN1_SUB(SEC_OctetStringTemplate) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSCMSKeyAgreeRecipientInfo,keyEncAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_SEQUENCE_OF, - offsetof(NSSCMSKeyAgreeRecipientInfo,recipientEncryptedKeys), - NSSCMSRecipientEncryptedKeyTemplate }, - { 0 } -}; - -/* ----------------------------------------------------------------------------- - * KEK recipient info - */ - -static const SEC_ASN1Template NSSCMSKEKIdentifierTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSKEKIdentifier) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSKEKIdentifier,keyIdentifier) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSKEKIdentifier,date) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSKEKIdentifier,other) }, - { 0 } -}; - -static const SEC_ASN1Template NSSCMSKEKRecipientInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSKEKRecipientInfo) }, - { SEC_ASN1_INTEGER, - offsetof(NSSCMSKEKRecipientInfo,version) }, - { SEC_ASN1_INLINE, - offsetof(NSSCMSKEKRecipientInfo,kekIdentifier), - NSSCMSKEKIdentifierTemplate }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSCMSKEKRecipientInfo,keyEncAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSKEKRecipientInfo,encKey) }, - { 0 } -}; - -/* ----------------------------------------------------------------------------- - * recipient info - */ -const SEC_ASN1Template NSSCMSRecipientInfoTemplate[] = { - { SEC_ASN1_CHOICE, - offsetof(NSSCMSRecipientInfo,recipientInfoType), NULL, - sizeof(NSSCMSRecipientInfo) }, - { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(NSSCMSRecipientInfo,ri.keyAgreeRecipientInfo), - NSSCMSKeyAgreeRecipientInfoTemplate, - NSSCMSRecipientInfoID_KeyAgree }, - { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2, - offsetof(NSSCMSRecipientInfo,ri.kekRecipientInfo), - NSSCMSKEKRecipientInfoTemplate, - NSSCMSRecipientInfoID_KEK }, - { SEC_ASN1_INLINE, - offsetof(NSSCMSRecipientInfo,ri.keyTransRecipientInfo), - NSSCMSKeyTransRecipientInfoTemplate, - NSSCMSRecipientInfoID_KeyTrans }, - { 0 } -}; - -/* ----------------------------------------------------------------------------- - * - */ - -const SEC_ASN1Template NSSCMSDigestedDataTemplate[] = { - { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, - 0, NULL, sizeof(NSSCMSDigestedData) }, - { SEC_ASN1_INTEGER, - offsetof(NSSCMSDigestedData,version) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSCMSDigestedData,digestAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_INLINE, - offsetof(NSSCMSDigestedData,contentInfo), - NSSCMSEncapsulatedContentInfoTemplate }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSDigestedData,digest) }, - { 0 } -}; - -const SEC_ASN1Template NSS_PointerToCMSDigestedDataTemplate[] = { - { SEC_ASN1_POINTER, 0, NSSCMSDigestedDataTemplate } -}; - -const SEC_ASN1Template NSSCMSEncryptedDataTemplate[] = { - { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, - 0, NULL, sizeof(NSSCMSEncryptedData) }, - { SEC_ASN1_INTEGER, - offsetof(NSSCMSEncryptedData,version) }, - { SEC_ASN1_INLINE, - offsetof(NSSCMSEncryptedData,contentInfo), - NSSCMSEncryptedContentInfoTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(NSSCMSEncryptedData,unprotectedAttr), - nss_cms_set_of_attribute_template }, - { 0 } -}; - -const SEC_ASN1Template NSS_PointerToCMSEncryptedDataTemplate[] = { - { SEC_ASN1_POINTER, 0, NSSCMSEncryptedDataTemplate } -}; - -/* ----------------------------------------------------------------------------- - * FORTEZZA KEA - */ -const SEC_ASN1Template NSS_SMIMEKEAParamTemplateSkipjack[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSSMIMEKEAParameters) }, - { SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */, - offsetof(NSSCMSSMIMEKEAParameters,originatorKEAKey) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSSMIMEKEAParameters,originatorRA) }, - { 0 } -}; - -const SEC_ASN1Template NSS_SMIMEKEAParamTemplateNoSkipjack[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSSMIMEKEAParameters) }, - { SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */, - offsetof(NSSCMSSMIMEKEAParameters,originatorKEAKey) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSSMIMEKEAParameters,originatorRA) }, - { SEC_ASN1_OCTET_STRING | SEC_ASN1_OPTIONAL , - offsetof(NSSCMSSMIMEKEAParameters,nonSkipjackIV) }, - { 0 } -}; - -const SEC_ASN1Template NSS_SMIMEKEAParamTemplateAllParams[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSSMIMEKEAParameters) }, - { SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */, - offsetof(NSSCMSSMIMEKEAParameters,originatorKEAKey) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSCMSSMIMEKEAParameters,originatorRA) }, - { SEC_ASN1_OCTET_STRING | SEC_ASN1_OPTIONAL , - offsetof(NSSCMSSMIMEKEAParameters,nonSkipjackIV) }, - { SEC_ASN1_OCTET_STRING | SEC_ASN1_OPTIONAL , - offsetof(NSSCMSSMIMEKEAParameters,bulkKeySize) }, - { 0 } -}; - -const SEC_ASN1Template * -nss_cms_get_kea_template(NSSCMSKEATemplateSelector whichTemplate) -{ - const SEC_ASN1Template *returnVal = NULL; - - switch(whichTemplate) - { - case NSSCMSKEAUsesNonSkipjack: - returnVal = NSS_SMIMEKEAParamTemplateNoSkipjack; - break; - case NSSCMSKEAUsesSkipjack: - returnVal = NSS_SMIMEKEAParamTemplateSkipjack; - break; - case NSSCMSKEAUsesNonSkipjackWithPaddedEncKey: - default: - returnVal = NSS_SMIMEKEAParamTemplateAllParams; - break; - } - return returnVal; -} - -/* ----------------------------------------------------------------------------- - * - */ -static const SEC_ASN1Template * -nss_cms_choose_content_template(void *src_or_dest, PRBool encoding) -{ - const SEC_ASN1Template *theTemplate; - NSSCMSContentInfo *cinfo; - - PORT_Assert (src_or_dest != NULL); - if (src_or_dest == NULL) - return NULL; - - cinfo = (NSSCMSContentInfo *)src_or_dest; - switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) { - default: - theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate); - break; - case SEC_OID_PKCS7_DATA: - theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate); - break; - case SEC_OID_PKCS7_SIGNED_DATA: - theTemplate = NSS_PointerToCMSSignedDataTemplate; - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - theTemplate = NSS_PointerToCMSEnvelopedDataTemplate; - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - theTemplate = NSS_PointerToCMSDigestedDataTemplate; - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - theTemplate = NSS_PointerToCMSEncryptedDataTemplate; - break; - } - return theTemplate; -} diff --git a/security/nss/lib/smime/cmsattr.c b/security/nss/lib/smime/cmsattr.c deleted file mode 100644 index 26d9dbb78..000000000 --- a/security/nss/lib/smime/cmsattr.c +++ /dev/null @@ -1,461 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS attributes. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "pk11func.h" -#include "prtime.h" -#include "secerr.h" - -/* - * ------------------------------------------------------------------- - * XXX The following Attribute stuff really belongs elsewhere. - * The Attribute type is *not* part of CMS but rather X.501. - * But for now, since CMS is the only customer of attributes, - * we define them here. Once there is a use outside of CMS, - * then change the attribute types and functions from internal - * to external naming convention, and move them elsewhere! - */ - - -/* - * NSS_CMSAttribute_Create - create an attribute - * - * if value is NULL, the attribute won't have a value. It can be added later - * with NSS_CMSAttribute_AddValue. - */ -NSSCMSAttribute * -NSS_CMSAttribute_Create(PRArenaPool *poolp, SECOidTag oidtag, SECItem *value, PRBool encoded) -{ - NSSCMSAttribute *attr; - SECItem *copiedvalue; - void *mark; - - PORT_Assert (poolp != NULL); - - mark = PORT_ArenaMark (poolp); - - attr = (NSSCMSAttribute *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSAttribute)); - if (attr == NULL) - goto loser; - - attr->typeTag = SECOID_FindOIDByTag(oidtag); - if (attr->typeTag == NULL) - goto loser; - - if (SECITEM_CopyItem(poolp, &(attr->type), &(attr->typeTag->oid)) != SECSuccess) - goto loser; - - if (value != NULL) { - if ((copiedvalue = SECITEM_ArenaDupItem(poolp, value)) == NULL) - goto loser; - - if (NSS_CMSArray_Add(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess) - goto loser; - } - - attr->encoded = encoded; - - PORT_ArenaUnmark (poolp, mark); - - return attr; - -loser: - PORT_Assert (mark != NULL); - PORT_ArenaRelease (poolp, mark); - return NULL; -} - -/* - * NSS_CMSAttribute_AddValue - add another value to an attribute - */ -SECStatus -NSS_CMSAttribute_AddValue(PLArenaPool *poolp, NSSCMSAttribute *attr, SECItem *value) -{ - SECItem *copiedvalue; - void *mark; - - PORT_Assert (poolp != NULL); - - mark = PORT_ArenaMark(poolp); - - if (value == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - goto loser; - } - - if ((copiedvalue = SECITEM_ArenaDupItem(poolp, value)) == NULL) - goto loser; - - if (NSS_CMSArray_Add(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess) - goto loser; - - PORT_ArenaUnmark(poolp, mark); - return SECSuccess; - -loser: - PORT_Assert (mark != NULL); - PORT_ArenaRelease (poolp, mark); - return SECFailure; -} - -/* - * NSS_CMSAttribute_GetType - return the OID tag - */ -SECOidTag -NSS_CMSAttribute_GetType(NSSCMSAttribute *attr) -{ - SECOidData *typetag; - - typetag = SECOID_FindOID(&(attr->type)); - if (typetag == NULL) - return SEC_OID_UNKNOWN; - - return typetag->offset; -} - -/* - * NSS_CMSAttribute_GetValue - return the first attribute value - * - * We do some sanity checking first: - * - Multiple values are *not* expected. - * - Empty values are *not* expected. - */ -SECItem * -NSS_CMSAttribute_GetValue(NSSCMSAttribute *attr) -{ - SECItem *value; - - if (attr == NULL) - return NULL; - - value = attr->values[0]; - - if (value == NULL || value->data == NULL || value->len == 0) - return NULL; - - if (attr->values[1] != NULL) - return NULL; - - return value; -} - -/* - * NSS_CMSAttribute_CompareValue - compare the attribute's first value against data - */ -PRBool -NSS_CMSAttribute_CompareValue(NSSCMSAttribute *attr, SECItem *av) -{ - SECItem *value; - - if (attr == NULL) - return PR_FALSE; - - value = NSS_CMSAttribute_GetValue(attr); - - return (value != NULL && value->len == av->len && - PORT_Memcmp (value->data, av->data, value->len) == 0); -} - -/* - * templates and functions for separate ASN.1 encoding of attributes - * - * used in NSS_CMSAttributeArray_Reorder - */ - -/* - * helper function for dynamic template determination of the attribute value - */ -static const SEC_ASN1Template * -cms_attr_choose_attr_value_template(void *src_or_dest, PRBool encoding) -{ - const SEC_ASN1Template *theTemplate; - NSSCMSAttribute *attribute; - SECOidData *oiddata; - PRBool encoded; - - PORT_Assert (src_or_dest != NULL); - if (src_or_dest == NULL) - return NULL; - - attribute = (NSSCMSAttribute *)src_or_dest; - - if (encoding && (!attribute->values || !attribute->values[0] || - attribute->encoded)) { - /* we're encoding, and the attribute has no value or the attribute - * value is already encoded. */ - return SEC_ASN1_GET(SEC_AnyTemplate); - } - - /* get attribute's typeTag */ - oiddata = attribute->typeTag; - if (oiddata == NULL) { - oiddata = SECOID_FindOID(&attribute->type); - attribute->typeTag = oiddata; - } - - if (oiddata == NULL) { - /* still no OID tag? OID is unknown then. en/decode value as ANY. */ - encoded = PR_TRUE; - theTemplate = SEC_ASN1_GET(SEC_AnyTemplate); - } else { - switch (oiddata->offset) { - case SEC_OID_PKCS9_SMIME_CAPABILITIES: - case SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE: - /* these guys need to stay DER-encoded */ - default: - /* same goes for OIDs that are not handled here */ - encoded = PR_TRUE; - theTemplate = SEC_ASN1_GET(SEC_AnyTemplate); - break; - /* otherwise choose proper template */ - case SEC_OID_PKCS9_EMAIL_ADDRESS: - case SEC_OID_RFC1274_MAIL: - case SEC_OID_PKCS9_UNSTRUCTURED_NAME: - encoded = PR_FALSE; - theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate); - break; - case SEC_OID_PKCS9_CONTENT_TYPE: - encoded = PR_FALSE; - theTemplate = SEC_ASN1_GET(SEC_ObjectIDTemplate); - break; - case SEC_OID_PKCS9_MESSAGE_DIGEST: - encoded = PR_FALSE; - theTemplate = SEC_ASN1_GET(SEC_OctetStringTemplate); - break; - case SEC_OID_PKCS9_SIGNING_TIME: - encoded = PR_FALSE; - theTemplate = SEC_ASN1_GET(CERT_TimeChoiceTemplate); - break; - /* XXX Want other types here, too */ - } - } - - if (encoding) { - /* - * If we are encoding and we think we have an already-encoded value, - * then the code which initialized this attribute should have set - * the "encoded" property to true (and we would have returned early, - * up above). No devastating error, but that code should be fixed. - * (It could indicate that the resulting encoded bytes are wrong.) - */ - PORT_Assert (!encoded); - } else { - /* - * We are decoding; record whether the resulting value is - * still encoded or not. - */ - attribute->encoded = encoded; - } - return theTemplate; -} - -static const SEC_ASN1TemplateChooserPtr cms_attr_chooser - = cms_attr_choose_attr_value_template; - -const SEC_ASN1Template nss_cms_attribute_template[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSCMSAttribute) }, - { SEC_ASN1_OBJECT_ID, - offsetof(NSSCMSAttribute,type) }, - { SEC_ASN1_DYNAMIC | SEC_ASN1_SET_OF, - offsetof(NSSCMSAttribute,values), - &cms_attr_chooser }, - { 0 } -}; - -const SEC_ASN1Template nss_cms_set_of_attribute_template[] = { - { SEC_ASN1_SET_OF, 0, nss_cms_attribute_template }, -}; - -/* ============================================================================= - * Attribute Array methods - */ - -/* - * NSS_CMSAttributeArray_Encode - encode an Attribute array as SET OF Attributes - * - * If you are wondering why this routine does not reorder the attributes - * first, and might be tempted to make it do so, see the comment by the - * call to ReorderAttributes in cmsencode.c. (Or, see who else calls this - * and think long and hard about the implications of making it always - * do the reordering.) - */ -SECItem * -NSS_CMSAttributeArray_Encode(PRArenaPool *poolp, NSSCMSAttribute ***attrs, SECItem *dest) -{ - return SEC_ASN1EncodeItem (poolp, dest, (void *)attrs, nss_cms_set_of_attribute_template); -} - -/* - * NSS_CMSAttributeArray_Reorder - sort attribute array by attribute's DER encoding - * - * make sure that the order of the attributes guarantees valid DER (which must be - * in lexigraphically ascending order for a SET OF); if reordering is necessary it - * will be done in place (in attrs). - */ -SECStatus -NSS_CMSAttributeArray_Reorder(NSSCMSAttribute **attrs) -{ - return NSS_CMSArray_SortByDER((void **)attrs, nss_cms_attribute_template, NULL); -} - -/* - * NSS_CMSAttributeArray_FindAttrByOidTag - look through a set of attributes and - * find one that matches the specified object ID. - * - * If "only" is true, then make sure that there is not more than one attribute - * of the same type. Otherwise, just return the first one found. (XXX Does - * anybody really want that first-found behavior? It was like that when I found it...) - */ -NSSCMSAttribute * -NSS_CMSAttributeArray_FindAttrByOidTag(NSSCMSAttribute **attrs, SECOidTag oidtag, PRBool only) -{ - SECOidData *oid; - NSSCMSAttribute *attr1, *attr2; - - if (attrs == NULL) - return NULL; - - oid = SECOID_FindOIDByTag(oidtag); - if (oid == NULL) - return NULL; - - while ((attr1 = *attrs++) != NULL) { - if (attr1->type.len == oid->oid.len && PORT_Memcmp (attr1->type.data, - oid->oid.data, - oid->oid.len) == 0) - break; - } - - if (attr1 == NULL) - return NULL; - - if (!only) - return attr1; - - while ((attr2 = *attrs++) != NULL) { - if (attr2->type.len == oid->oid.len && PORT_Memcmp (attr2->type.data, - oid->oid.data, - oid->oid.len) == 0) - break; - } - - if (attr2 != NULL) - return NULL; - - return attr1; -} - -/* - * NSS_CMSAttributeArray_AddAttr - add an attribute to an - * array of attributes. - */ -SECStatus -NSS_CMSAttributeArray_AddAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, NSSCMSAttribute *attr) -{ - NSSCMSAttribute *oattr; - void *mark; - SECOidTag type; - - mark = PORT_ArenaMark(poolp); - - /* find oidtag of attr */ - type = NSS_CMSAttribute_GetType(attr); - - /* see if we have one already */ - oattr = NSS_CMSAttributeArray_FindAttrByOidTag(*attrs, type, PR_FALSE); - PORT_Assert (oattr == NULL); - if (oattr != NULL) - goto loser; /* XXX or would it be better to replace it? */ - - /* no, shove it in */ - if (NSS_CMSArray_Add(poolp, (void ***)attrs, (void *)attr) != SECSuccess) - goto loser; - - PORT_ArenaUnmark(poolp, mark); - return SECSuccess; - -loser: - PORT_ArenaRelease(poolp, mark); - return SECFailure; -} - -/* - * NSS_CMSAttributeArray_SetAttr - set an attribute's value in a set of attributes - */ -SECStatus -NSS_CMSAttributeArray_SetAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, SECOidTag type, SECItem *value, PRBool encoded) -{ - NSSCMSAttribute *attr; - void *mark; - - mark = PORT_ArenaMark(poolp); - - /* see if we have one already */ - attr = NSS_CMSAttributeArray_FindAttrByOidTag(*attrs, type, PR_FALSE); - if (attr == NULL) { - /* not found? create one! */ - attr = NSS_CMSAttribute_Create(poolp, type, value, encoded); - if (attr == NULL) - goto loser; - /* and add it to the list */ - if (NSS_CMSArray_Add(poolp, (void ***)attrs, (void *)attr) != SECSuccess) - goto loser; - } else { - /* found, shove it in */ - /* XXX we need a decent memory model @#$#$!#!!! */ - attr->values[0] = value; - attr->encoded = encoded; - } - - PORT_ArenaUnmark (poolp, mark); - return SECSuccess; - -loser: - PORT_ArenaRelease (poolp, mark); - return SECFailure; -} - diff --git a/security/nss/lib/smime/cmscinfo.c b/security/nss/lib/smime/cmscinfo.c deleted file mode 100644 index 1129ea33e..000000000 --- a/security/nss/lib/smime/cmscinfo.c +++ /dev/null @@ -1,360 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS contentInfo methods. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "pk11func.h" -#include "secitem.h" -#include "secoid.h" -#include "secerr.h" - -/* - * NSS_CMSContentInfo_Create - create a content info - * - * version is set in the _Finalize procedures for each content type - */ - -/* - * NSS_CMSContentInfo_Destroy - destroy a CMS contentInfo and all of its sub-pieces. - */ -void -NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo) -{ - SECOidTag kind; - - kind = NSS_CMSContentInfo_GetContentTypeTag(cinfo); - switch (kind) { - case SEC_OID_PKCS7_ENVELOPED_DATA: - NSS_CMSEnvelopedData_Destroy(cinfo->content.envelopedData); - break; - case SEC_OID_PKCS7_SIGNED_DATA: - NSS_CMSSignedData_Destroy(cinfo->content.signedData); - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - NSS_CMSEncryptedData_Destroy(cinfo->content.encryptedData); - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - NSS_CMSDigestedData_Destroy(cinfo->content.digestedData); - break; - default: - /* XXX Anything else that needs to be "manually" freed/destroyed? */ - break; - } - if (cinfo->digcx) { - /* must destroy digest objects */ - NSS_CMSDigestContext_Cancel(cinfo->digcx); - cinfo->digcx = NULL; - } - if (cinfo->bulkkey) - PK11_FreeSymKey(cinfo->bulkkey); - - if (cinfo->ciphcx) { - NSS_CMSCipherContext_Destroy(cinfo->ciphcx); - cinfo->ciphcx = NULL; - } - - /* we live in a pool, so no need to worry about storage */ -} - -/* - * NSS_CMSContentInfo_GetChildContentInfo - get content's contentInfo (if it exists) - */ -NSSCMSContentInfo * -NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo) -{ - void * ptr = NULL; - NSSCMSContentInfo * ccinfo = NULL; - SECOidTag tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo); - switch (tag) { - case SEC_OID_PKCS7_SIGNED_DATA: - ptr = (void *)cinfo->content.signedData; - ccinfo = &(cinfo->content.signedData->contentInfo); - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - ptr = (void *)cinfo->content.envelopedData; - ccinfo = &(cinfo->content.envelopedData->contentInfo); - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - ptr = (void *)cinfo->content.digestedData; - ccinfo = &(cinfo->content.digestedData->contentInfo); - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - ptr = (void *)cinfo->content.encryptedData; - ccinfo = &(cinfo->content.encryptedData->contentInfo); - break; - case SEC_OID_PKCS7_DATA: - default: - break; - } - return (ptr ? ccinfo : NULL); -} - -/* - * NSS_CMSContentInfo_SetContent - set content type & content - */ -SECStatus -NSS_CMSContentInfo_SetContent(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECOidTag type, void *ptr) -{ - SECStatus rv; - - cinfo->contentTypeTag = SECOID_FindOIDByTag(type); - if (cinfo->contentTypeTag == NULL) - return SECFailure; - - /* do not copy the oid, just create a reference */ - rv = SECITEM_CopyItem (cmsg->poolp, &(cinfo->contentType), &(cinfo->contentTypeTag->oid)); - if (rv != SECSuccess) - return SECFailure; - - cinfo->content.pointer = ptr; - - if (type != SEC_OID_PKCS7_DATA) { - /* as we always have some inner data, - * we need to set it to something, just to fool the encoder enough to work on it - * and get us into nss_cms_encoder_notify at that point */ - cinfo->rawContent = SECITEM_AllocItem(cmsg->poolp, NULL, 1); - if (cinfo->rawContent == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } - } - - return SECSuccess; -} - -/* - * NSS_CMSContentInfo_SetContent_XXXX - typesafe wrappers for NSS_CMSContentInfo_SetContent - */ - -/* - * data == NULL -> pass in data via NSS_CMSEncoder_Update - * data != NULL -> take this data - */ -SECStatus -NSS_CMSContentInfo_SetContent_Data(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECItem *data, PRBool detached) -{ - if (NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DATA, (void *)data) != SECSuccess) - return SECFailure; - cinfo->rawContent = (detached) ? - NULL : (data) ? - data : SECITEM_AllocItem(cmsg->poolp, NULL, 1); - return SECSuccess; -} - -SECStatus -NSS_CMSContentInfo_SetContent_SignedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSSignedData *sigd) -{ - return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_SIGNED_DATA, (void *)sigd); -} - -SECStatus -NSS_CMSContentInfo_SetContent_EnvelopedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEnvelopedData *envd) -{ - return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENVELOPED_DATA, (void *)envd); -} - -SECStatus -NSS_CMSContentInfo_SetContent_DigestedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSDigestedData *digd) -{ - return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DIGESTED_DATA, (void *)digd); -} - -SECStatus -NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEncryptedData *encd) -{ - return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENCRYPTED_DATA, (void *)encd); -} - -/* - * NSS_CMSContentInfo_GetContent - get pointer to inner content - * - * needs to be casted... - */ -void * -NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo) -{ - SECOidTag tag = (cinfo && cinfo->contentTypeTag) - ? cinfo->contentTypeTag->offset - : SEC_OID_UNKNOWN; - switch (tag) { - case SEC_OID_PKCS7_DATA: - case SEC_OID_PKCS7_SIGNED_DATA: - case SEC_OID_PKCS7_ENVELOPED_DATA: - case SEC_OID_PKCS7_DIGESTED_DATA: - case SEC_OID_PKCS7_ENCRYPTED_DATA: - return cinfo->content.pointer; - default: - return NULL; - } -} - -/* - * NSS_CMSContentInfo_GetInnerContent - get pointer to innermost content - * - * this is typically only called by NSS_CMSMessage_GetContent() - */ -SECItem * -NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo) -{ - NSSCMSContentInfo *ccinfo; - SECOidTag tag; - SECItem *pItem = NULL; - - tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo); - switch (tag) { - case SEC_OID_PKCS7_DATA: - /* end of recursion - every message has to have a data cinfo */ - pItem = cinfo->content.data; - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - case SEC_OID_PKCS7_ENCRYPTED_DATA: - case SEC_OID_PKCS7_ENVELOPED_DATA: - case SEC_OID_PKCS7_SIGNED_DATA: - ccinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo); - if (ccinfo != NULL) - pItem = NSS_CMSContentInfo_GetContent(ccinfo); - break; - default: - PORT_Assert(0); - break; - } - return pItem; -} - -/* - * NSS_CMSContentInfo_GetContentType{Tag,OID} - find out (saving pointer to lookup result - * for future reference) and return the inner content type. - */ -SECOidTag -NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo) -{ - if (cinfo->contentTypeTag == NULL) - cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); - - if (cinfo->contentTypeTag == NULL) - return SEC_OID_UNKNOWN; - - return cinfo->contentTypeTag->offset; -} - -SECItem * -NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo) -{ - if (cinfo->contentTypeTag == NULL) - cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); - - if (cinfo->contentTypeTag == NULL) - return NULL; - - return &(cinfo->contentTypeTag->oid); -} - -/* - * NSS_CMSContentInfo_GetContentEncAlgTag - find out (saving pointer to lookup result - * for future reference) and return the content encryption algorithm tag. - */ -SECOidTag -NSS_CMSContentInfo_GetContentEncAlgTag(NSSCMSContentInfo *cinfo) -{ - if (cinfo->contentEncAlgTag == SEC_OID_UNKNOWN) - cinfo->contentEncAlgTag = SECOID_GetAlgorithmTag(&(cinfo->contentEncAlg)); - - return cinfo->contentEncAlgTag; -} - -/* - * NSS_CMSContentInfo_GetContentEncAlg - find out and return the content encryption algorithm tag. - */ -SECAlgorithmID * -NSS_CMSContentInfo_GetContentEncAlg(NSSCMSContentInfo *cinfo) -{ - return &(cinfo->contentEncAlg); -} - -SECStatus -NSS_CMSContentInfo_SetContentEncAlg(PLArenaPool *poolp, NSSCMSContentInfo *cinfo, - SECOidTag bulkalgtag, SECItem *parameters, int keysize) -{ - SECStatus rv; - - rv = SECOID_SetAlgorithmID(poolp, &(cinfo->contentEncAlg), bulkalgtag, parameters); - if (rv != SECSuccess) - return SECFailure; - cinfo->keysize = keysize; - return SECSuccess; -} - -SECStatus -NSS_CMSContentInfo_SetContentEncAlgID(PLArenaPool *poolp, NSSCMSContentInfo *cinfo, - SECAlgorithmID *algid, int keysize) -{ - SECStatus rv; - - rv = SECOID_CopyAlgorithmID(poolp, &(cinfo->contentEncAlg), algid); - if (rv != SECSuccess) - return SECFailure; - if (keysize >= 0) - cinfo->keysize = keysize; - return SECSuccess; -} - -void -NSS_CMSContentInfo_SetBulkKey(NSSCMSContentInfo *cinfo, PK11SymKey *bulkkey) -{ - cinfo->bulkkey = PK11_ReferenceSymKey(bulkkey); - cinfo->keysize = PK11_GetKeyStrength(cinfo->bulkkey, &(cinfo->contentEncAlg)); -} - -PK11SymKey * -NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo *cinfo) -{ - if (cinfo->bulkkey == NULL) - return NULL; - - return PK11_ReferenceSymKey(cinfo->bulkkey); -} - -int -NSS_CMSContentInfo_GetBulkKeySize(NSSCMSContentInfo *cinfo) -{ - return cinfo->keysize; -} diff --git a/security/nss/lib/smime/cmscipher.c b/security/nss/lib/smime/cmscipher.c deleted file mode 100644 index 00042937a..000000000 --- a/security/nss/lib/smime/cmscipher.c +++ /dev/null @@ -1,788 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * Encryption/decryption routines for CMS implementation, none of which are exported. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "secoid.h" -#include "secitem.h" -#include "pk11func.h" -#include "secerr.h" -#include "secpkcs5.h" - -/* - * ------------------------------------------------------------------- - * Cipher stuff. - */ - -typedef SECStatus (*nss_cms_cipher_function) (void *, unsigned char *, unsigned int *, - unsigned int, const unsigned char *, unsigned int); -typedef SECStatus (*nss_cms_cipher_destroy) (void *, PRBool); - -#define BLOCK_SIZE 4096 - -struct NSSCMSCipherContextStr { - void * cx; /* PK11 cipher context */ - nss_cms_cipher_function doit; - nss_cms_cipher_destroy destroy; - PRBool encrypt; /* encrypt / decrypt switch */ - int block_size; /* block & pad sizes for cipher */ - int pad_size; - int pending_count; /* pending data (not yet en/decrypted */ - unsigned char pending_buf[BLOCK_SIZE];/* because of blocking */ -}; - -/* - * NSS_CMSCipherContext_StartDecrypt - create a cipher context to do decryption - * based on the given bulk * encryption key and algorithm identifier (which may include an iv). - * - * XXX Once both are working, it might be nice to combine this and the - * function below (for starting up encryption) into one routine, and just - * have two simple cover functions which call it. - */ -NSSCMSCipherContext * -NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid) -{ - NSSCMSCipherContext *cc; - void *ciphercx; - CK_MECHANISM_TYPE mechanism; - SECItem *param; - PK11SlotInfo *slot; - SECOidTag algtag; - - algtag = SECOID_GetAlgorithmTag(algid); - - /* set param and mechanism */ - if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { - CK_MECHANISM pbeMech, cryptoMech; - SECItem *pbeParams, *pwitem; - - PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM)); - PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM)); - - pwitem = PK11_GetSymKeyUserData(key); - if (!pwitem) - return NULL; - - /* find correct PK11 mechanism and parameters to initialize pbeMech */ - pbeMech.mechanism = PK11_AlgtagToMechanism(algtag); - pbeParams = PK11_ParamFromAlgid(algid); - if (!pbeParams) - return NULL; - pbeMech.pParameter = pbeParams->data; - pbeMech.ulParameterLen = pbeParams->len; - - /* now map pbeMech to cryptoMech */ - if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, pwitem, - PR_FALSE) != CKR_OK) { - SECITEM_ZfreeItem(pbeParams, PR_TRUE); - return NULL; - } - SECITEM_ZfreeItem(pbeParams, PR_TRUE); - - /* and use it to initialize param & mechanism */ - if ((param = (SECItem *)PORT_ZAlloc(sizeof(SECItem))) == NULL) - return NULL; - - param->data = (unsigned char *)cryptoMech.pParameter; - param->len = cryptoMech.ulParameterLen; - mechanism = cryptoMech.mechanism; - } else { - mechanism = PK11_AlgtagToMechanism(algtag); - if ((param = PK11_ParamFromAlgid(algid)) == NULL) - return NULL; - } - - cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext)); - if (cc == NULL) { - SECITEM_FreeItem(param,PR_TRUE); - return NULL; - } - - /* figure out pad and block sizes */ - cc->pad_size = PK11_GetBlockSize(mechanism, param); - slot = PK11_GetSlotFromKey(key); - cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size; - PK11_FreeSlot(slot); - - /* create PK11 cipher context */ - ciphercx = PK11_CreateContextBySymKey(mechanism, CKA_DECRYPT, key, param); - SECITEM_FreeItem(param, PR_TRUE); - if (ciphercx == NULL) { - PORT_Free (cc); - return NULL; - } - - cc->cx = ciphercx; - cc->doit = (nss_cms_cipher_function) PK11_CipherOp; - cc->destroy = (nss_cms_cipher_destroy) PK11_DestroyContext; - cc->encrypt = PR_FALSE; - cc->pending_count = 0; - - return cc; -} - -/* - * NSS_CMSCipherContext_StartEncrypt - create a cipher object to do encryption, - * based on the given bulk encryption key and algorithm tag. Fill in the algorithm - * identifier (which may include an iv) appropriately. - * - * XXX Once both are working, it might be nice to combine this and the - * function above (for starting up decryption) into one routine, and just - * have two simple cover functions which call it. - */ -NSSCMSCipherContext * -NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgorithmID *algid) -{ - NSSCMSCipherContext *cc; - void *ciphercx; - SECItem *param; - SECStatus rv; - CK_MECHANISM_TYPE mechanism; - PK11SlotInfo *slot; - PRBool needToEncodeAlgid = PR_FALSE; - SECOidTag algtag = SECOID_GetAlgorithmTag(algid); - - /* set param and mechanism */ - if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { - CK_MECHANISM pbeMech, cryptoMech; - SECItem *pbeParams, *pwitem; - - PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM)); - PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM)); - - pwitem = PK11_GetSymKeyUserData(key); - if (!pwitem) - return NULL; - - /* find correct PK11 mechanism and parameters to initialize pbeMech */ - pbeMech.mechanism = PK11_AlgtagToMechanism(algtag); - pbeParams = PK11_ParamFromAlgid(algid); - if (!pbeParams) - return NULL; - pbeMech.pParameter = pbeParams->data; - pbeMech.ulParameterLen = pbeParams->len; - - /* now map pbeMech to cryptoMech */ - if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, pwitem, - PR_FALSE) != CKR_OK) { - SECITEM_ZfreeItem(pbeParams, PR_TRUE); - return NULL; - } - SECITEM_ZfreeItem(pbeParams, PR_TRUE); - - /* and use it to initialize param & mechanism */ - if ((param = (SECItem *)PORT_ZAlloc(sizeof(SECItem))) == NULL) - return NULL; - - param->data = (unsigned char *)cryptoMech.pParameter; - param->len = cryptoMech.ulParameterLen; - mechanism = cryptoMech.mechanism; - } else { - mechanism = PK11_AlgtagToMechanism(algtag); - if ((param = PK11_GenerateNewParam(mechanism, key)) == NULL) - return NULL; - needToEncodeAlgid = PR_TRUE; - } - - cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext)); - if (cc == NULL) - return NULL; - - /* now find pad and block sizes for our mechanism */ - cc->pad_size = PK11_GetBlockSize(mechanism,param); - slot = PK11_GetSlotFromKey(key); - cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size; - PK11_FreeSlot(slot); - - /* and here we go, creating a PK11 cipher context */ - ciphercx = PK11_CreateContextBySymKey(mechanism, CKA_ENCRYPT, key, param); - if (ciphercx == NULL) { - PORT_Free(cc); - cc = NULL; - goto loser; - } - - /* - * These are placed after the CreateContextBySymKey() because some - * mechanisms have to generate their IVs from their card (i.e. FORTEZZA). - * Don't move it from here. - * XXX is that right? the purpose of this is to get the correct algid - * containing the IVs etc. for encoding. this means we need to set this up - * BEFORE encoding the algid in the contentInfo, right? - */ - if (needToEncodeAlgid) { - rv = PK11_ParamToAlgid(algtag, param, poolp, algid); - if(rv != SECSuccess) { - PORT_Free(cc); - cc = NULL; - goto loser; - } - } - - cc->cx = ciphercx; - cc->doit = (nss_cms_cipher_function)PK11_CipherOp; - cc->destroy = (nss_cms_cipher_destroy)PK11_DestroyContext; - cc->encrypt = PR_TRUE; - cc->pending_count = 0; - -loser: - SECITEM_FreeItem(param, PR_TRUE); - - return cc; -} - -void -NSS_CMSCipherContext_Destroy(NSSCMSCipherContext *cc) -{ - PORT_Assert(cc != NULL); - if (cc == NULL) - return; - (*cc->destroy)(cc->cx, PR_TRUE); - PORT_Free(cc); -} - -/* - * NSS_CMSCipherContext_DecryptLength - find the output length of the next call to decrypt. - * - * cc - the cipher context - * input_len - number of bytes used as input - * final - true if this is the final chunk of data - * - * Result can be used to perform memory allocations. Note that the amount - * is exactly accurate only when not doing a block cipher or when final - * is false, otherwise it is an upper bound on the amount because until - * we see the data we do not know how many padding bytes there are - * (always between 1 and bsize). - * - * Note that this can return zero, which does not mean that the decrypt - * operation can be skipped! (It simply means that there are not enough - * bytes to make up an entire block; the bytes will be reserved until - * there are enough to encrypt/decrypt at least one block.) However, - * if zero is returned it *does* mean that no output buffer need be - * passed in to the subsequent decrypt operation, as no output bytes - * will be stored. - */ -unsigned int -NSS_CMSCipherContext_DecryptLength(NSSCMSCipherContext *cc, unsigned int input_len, PRBool final) -{ - int blocks, block_size; - - PORT_Assert (! cc->encrypt); - - block_size = cc->block_size; - - /* - * If this is not a block cipher, then we always have the same - * number of output bytes as we had input bytes. - */ - if (block_size == 0) - return input_len; - - /* - * On the final call, we will always use up all of the pending - * bytes plus all of the input bytes, *but*, there will be padding - * at the end and we cannot predict how many bytes of padding we - * will end up removing. The amount given here is actually known - * to be at least 1 byte too long (because we know we will have - * at least 1 byte of padding), but seemed clearer/better to me. - */ - if (final) - return cc->pending_count + input_len; - - /* - * Okay, this amount is exactly what we will output on the - * next cipher operation. We will always hang onto the last - * 1 - block_size bytes for non-final operations. That is, - * we will do as many complete blocks as we can *except* the - * last block (complete or partial). (This is because until - * we know we are at the end, we cannot know when to interpret - * and removing the padding byte(s), which are guaranteed to - * be there.) - */ - blocks = (cc->pending_count + input_len - 1) / block_size; - return blocks * block_size; -} - -/* - * NSS_CMSCipherContext_EncryptLength - find the output length of the next call to encrypt. - * - * cc - the cipher context - * input_len - number of bytes used as input - * final - true if this is the final chunk of data - * - * Result can be used to perform memory allocations. - * - * Note that this can return zero, which does not mean that the encrypt - * operation can be skipped! (It simply means that there are not enough - * bytes to make up an entire block; the bytes will be reserved until - * there are enough to encrypt/decrypt at least one block.) However, - * if zero is returned it *does* mean that no output buffer need be - * passed in to the subsequent encrypt operation, as no output bytes - * will be stored. - */ -unsigned int -NSS_CMSCipherContext_EncryptLength(NSSCMSCipherContext *cc, unsigned int input_len, PRBool final) -{ - int blocks, block_size; - int pad_size; - - PORT_Assert (cc->encrypt); - - block_size = cc->block_size; - pad_size = cc->pad_size; - - /* - * If this is not a block cipher, then we always have the same - * number of output bytes as we had input bytes. - */ - if (block_size == 0) - return input_len; - - /* - * On the final call, we only send out what we need for - * remaining bytes plus the padding. (There is always padding, - * so even if we have an exact number of blocks as input, we - * will add another full block that is just padding.) - */ - if (final) { - if (pad_size == 0) { - return cc->pending_count + input_len; - } else { - blocks = (cc->pending_count + input_len) / pad_size; - blocks++; - return blocks*pad_size; - } - } - - /* - * Now, count the number of complete blocks of data we have. - */ - blocks = (cc->pending_count + input_len) / block_size; - - - return blocks * block_size; -} - - -/* - * NSS_CMSCipherContext_Decrypt - do the decryption - * - * cc - the cipher context - * output - buffer for decrypted result bytes - * output_len_p - number of bytes in output - * max_output_len - upper bound on bytes to put into output - * input - pointer to input bytes - * input_len - number of input bytes - * final - true if this is the final chunk of data - * - * Decrypts a given length of input buffer (starting at "input" and - * containing "input_len" bytes), placing the decrypted bytes in - * "output" and storing the output length in "*output_len_p". - * "cc" is the return value from NSS_CMSCipher_StartDecrypt. - * When "final" is true, this is the last of the data to be decrypted. - * - * This is much more complicated than it sounds when the cipher is - * a block-type, meaning that the decryption function will only - * operate on whole blocks. But our caller is operating stream-wise, - * and can pass in any number of bytes. So we need to keep track - * of block boundaries. We save excess bytes between calls in "cc". - * We also need to determine which bytes are padding, and remove - * them from the output. We can only do this step when we know we - * have the final block of data. PKCS #7 specifies that the padding - * used for a block cipher is a string of bytes, each of whose value is - * the same as the length of the padding, and that all data is padded. - * (Even data that starts out with an exact multiple of blocks gets - * added to it another block, all of which is padding.) - */ -SECStatus -NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output, - unsigned int *output_len_p, unsigned int max_output_len, - const unsigned char *input, unsigned int input_len, - PRBool final) -{ - int blocks, bsize, pcount, padsize; - unsigned int max_needed, ifraglen, ofraglen, output_len; - unsigned char *pbuf; - SECStatus rv; - - PORT_Assert (! cc->encrypt); - - /* - * Check that we have enough room for the output. Our caller should - * already handle this; failure is really an internal error (i.e. bug). - */ - max_needed = NSS_CMSCipherContext_DecryptLength(cc, input_len, final); - PORT_Assert (max_output_len >= max_needed); - if (max_output_len < max_needed) { - /* PORT_SetError (XXX); */ - return SECFailure; - } - - /* - * hardware encryption does not like small decryption sizes here, so we - * allow both blocking and padding. - */ - bsize = cc->block_size; - padsize = cc->pad_size; - - /* - * When no blocking or padding work to do, we can simply call the - * cipher function and we are done. - */ - if (bsize == 0) { - return (* cc->doit) (cc->cx, output, output_len_p, max_output_len, - input, input_len); - } - - pcount = cc->pending_count; - pbuf = cc->pending_buf; - - output_len = 0; - - if (pcount) { - /* - * Try to fill in an entire block, starting with the bytes - * we already have saved away. - */ - while (input_len && pcount < bsize) { - pbuf[pcount++] = *input++; - input_len--; - } - /* - * If we have at most a whole block and this is not our last call, - * then we are done for now. (We do not try to decrypt a lone - * single block because we cannot interpret the padding bytes - * until we know we are handling the very last block of all input.) - */ - if (input_len == 0 && !final) { - cc->pending_count = pcount; - if (output_len_p) - *output_len_p = 0; - return SECSuccess; - } - /* - * Given the logic above, we expect to have a full block by now. - * If we do not, there is something wrong, either with our own - * logic or with (length of) the data given to us. - */ - if ((padsize != 0) && (pcount % padsize) != 0) { - PORT_Assert (final); - PORT_SetError (SEC_ERROR_BAD_DATA); - return SECFailure; - } - /* - * Decrypt the block. - */ - rv = (*cc->doit)(cc->cx, output, &ofraglen, max_output_len, - pbuf, pcount); - if (rv != SECSuccess) - return rv; - - /* - * For now anyway, all of our ciphers have the same number of - * bytes of output as they do input. If this ever becomes untrue, - * then NSS_CMSCipherContext_DecryptLength needs to be made smarter! - */ - PORT_Assert(ofraglen == pcount); - - /* - * Account for the bytes now in output. - */ - max_output_len -= ofraglen; - output_len += ofraglen; - output += ofraglen; - } - - /* - * If this is our last call, we expect to have an exact number of - * blocks left to be decrypted; we will decrypt them all. - * - * If not our last call, we always save between 1 and bsize bytes - * until next time. (We must do this because we cannot be sure - * that none of the decrypted bytes are padding bytes until we - * have at least another whole block of data. You cannot tell by - * looking -- the data could be anything -- you can only tell by - * context, knowing you are looking at the last block.) We could - * decrypt a whole block now but it is easier if we just treat it - * the same way we treat partial block bytes. - */ - if (final) { - if (padsize) { - blocks = input_len / padsize; - ifraglen = blocks * padsize; - } else ifraglen = input_len; - PORT_Assert (ifraglen == input_len); - - if (ifraglen != input_len) { - PORT_SetError(SEC_ERROR_BAD_DATA); - return SECFailure; - } - } else { - blocks = (input_len - 1) / bsize; - ifraglen = blocks * bsize; - PORT_Assert (ifraglen < input_len); - - pcount = input_len - ifraglen; - PORT_Memcpy (pbuf, input + ifraglen, pcount); - cc->pending_count = pcount; - } - - if (ifraglen) { - rv = (* cc->doit)(cc->cx, output, &ofraglen, max_output_len, - input, ifraglen); - if (rv != SECSuccess) - return rv; - - /* - * For now anyway, all of our ciphers have the same number of - * bytes of output as they do input. If this ever becomes untrue, - * then sec_PKCS7DecryptLength needs to be made smarter! - */ - PORT_Assert (ifraglen == ofraglen); - if (ifraglen != ofraglen) { - PORT_SetError(SEC_ERROR_BAD_DATA); - return SECFailure; - } - - output_len += ofraglen; - } else { - ofraglen = 0; - } - - /* - * If we just did our very last block, "remove" the padding by - * adjusting the output length. - */ - if (final && (padsize != 0)) { - unsigned int padlen = *(output + ofraglen - 1); - - if (padlen == 0 || padlen > padsize) { - PORT_SetError(SEC_ERROR_BAD_DATA); - return SECFailure; - } - output_len -= padlen; - } - - PORT_Assert (output_len_p != NULL || output_len == 0); - if (output_len_p != NULL) - *output_len_p = output_len; - - return SECSuccess; -} - -/* - * NSS_CMSCipherContext_Encrypt - do the encryption - * - * cc - the cipher context - * output - buffer for decrypted result bytes - * output_len_p - number of bytes in output - * max_output_len - upper bound on bytes to put into output - * input - pointer to input bytes - * input_len - number of input bytes - * final - true if this is the final chunk of data - * - * Encrypts a given length of input buffer (starting at "input" and - * containing "input_len" bytes), placing the encrypted bytes in - * "output" and storing the output length in "*output_len_p". - * "cc" is the return value from NSS_CMSCipher_StartEncrypt. - * When "final" is true, this is the last of the data to be encrypted. - * - * This is much more complicated than it sounds when the cipher is - * a block-type, meaning that the encryption function will only - * operate on whole blocks. But our caller is operating stream-wise, - * and can pass in any number of bytes. So we need to keep track - * of block boundaries. We save excess bytes between calls in "cc". - * We also need to add padding bytes at the end. PKCS #7 specifies - * that the padding used for a block cipher is a string of bytes, - * each of whose value is the same as the length of the padding, - * and that all data is padded. (Even data that starts out with - * an exact multiple of blocks gets added to it another block, - * all of which is padding.) - * - * XXX I would kind of like to combine this with the function above - * which does decryption, since they have a lot in common. But the - * tricky parts about padding and filling blocks would be much - * harder to read that way, so I left them separate. At least for - * now until it is clear that they are right. - */ -SECStatus -NSS_CMSCipherContext_Encrypt(NSSCMSCipherContext *cc, unsigned char *output, - unsigned int *output_len_p, unsigned int max_output_len, - const unsigned char *input, unsigned int input_len, - PRBool final) -{ - int blocks, bsize, padlen, pcount, padsize; - unsigned int max_needed, ifraglen, ofraglen, output_len; - unsigned char *pbuf; - SECStatus rv; - - PORT_Assert (cc->encrypt); - - /* - * Check that we have enough room for the output. Our caller should - * already handle this; failure is really an internal error (i.e. bug). - */ - max_needed = NSS_CMSCipherContext_EncryptLength (cc, input_len, final); - PORT_Assert (max_output_len >= max_needed); - if (max_output_len < max_needed) { - /* PORT_SetError (XXX); */ - return SECFailure; - } - - bsize = cc->block_size; - padsize = cc->pad_size; - - /* - * When no blocking and padding work to do, we can simply call the - * cipher function and we are done. - */ - if (bsize == 0) { - return (*cc->doit)(cc->cx, output, output_len_p, max_output_len, - input, input_len); - } - - pcount = cc->pending_count; - pbuf = cc->pending_buf; - - output_len = 0; - - if (pcount) { - /* - * Try to fill in an entire block, starting with the bytes - * we already have saved away. - */ - while (input_len && pcount < bsize) { - pbuf[pcount++] = *input++; - input_len--; - } - /* - * If we do not have a full block and we know we will be - * called again, then we are done for now. - */ - if (pcount < bsize && !final) { - cc->pending_count = pcount; - if (output_len_p != NULL) - *output_len_p = 0; - return SECSuccess; - } - /* - * If we have a whole block available, encrypt it. - */ - if ((padsize == 0) || (pcount % padsize) == 0) { - rv = (* cc->doit) (cc->cx, output, &ofraglen, max_output_len, - pbuf, pcount); - if (rv != SECSuccess) - return rv; - - /* - * For now anyway, all of our ciphers have the same number of - * bytes of output as they do input. If this ever becomes untrue, - * then sec_PKCS7EncryptLength needs to be made smarter! - */ - PORT_Assert (ofraglen == pcount); - - /* - * Account for the bytes now in output. - */ - max_output_len -= ofraglen; - output_len += ofraglen; - output += ofraglen; - - pcount = 0; - } - } - - if (input_len) { - PORT_Assert (pcount == 0); - - blocks = input_len / bsize; - ifraglen = blocks * bsize; - - if (ifraglen) { - rv = (* cc->doit) (cc->cx, output, &ofraglen, max_output_len, - input, ifraglen); - if (rv != SECSuccess) - return rv; - - /* - * For now anyway, all of our ciphers have the same number of - * bytes of output as they do input. If this ever becomes untrue, - * then sec_PKCS7EncryptLength needs to be made smarter! - */ - PORT_Assert (ifraglen == ofraglen); - - max_output_len -= ofraglen; - output_len += ofraglen; - output += ofraglen; - } - - pcount = input_len - ifraglen; - PORT_Assert (pcount < bsize); - if (pcount) - PORT_Memcpy (pbuf, input + ifraglen, pcount); - } - - if (final) { - padlen = padsize - (pcount % padsize); - PORT_Memset (pbuf + pcount, padlen, padlen); - rv = (* cc->doit) (cc->cx, output, &ofraglen, max_output_len, - pbuf, pcount+padlen); - if (rv != SECSuccess) - return rv; - - /* - * For now anyway, all of our ciphers have the same number of - * bytes of output as they do input. If this ever becomes untrue, - * then sec_PKCS7EncryptLength needs to be made smarter! - */ - PORT_Assert (ofraglen == (pcount+padlen)); - output_len += ofraglen; - } else { - cc->pending_count = pcount; - } - - PORT_Assert (output_len_p != NULL || output_len == 0); - if (output_len_p != NULL) - *output_len_p = output_len; - - return SECSuccess; -} diff --git a/security/nss/lib/smime/cmsdecode.c b/security/nss/lib/smime/cmsdecode.c deleted file mode 100644 index 585371701..000000000 --- a/security/nss/lib/smime/cmsdecode.c +++ /dev/null @@ -1,742 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS decoding. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "cert.h" -#include "key.h" -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "prtime.h" -#include "secerr.h" - -struct NSSCMSDecoderContextStr { - SEC_ASN1DecoderContext * dcx; /* ASN.1 decoder context */ - NSSCMSMessage * cmsg; /* backpointer to the root message */ - SECOidTag type; /* type of message */ - NSSCMSContent content; /* pointer to message */ - NSSCMSDecoderContext * childp7dcx; /* inner CMS decoder context */ - PRBool saw_contents; - int error; - NSSCMSContentCallback cb; - void * cb_arg; -}; - -struct NSSCMSDecoderDataStr { - SECItem data; /* must be first */ - unsigned int totalBufferSize; -}; - -typedef struct NSSCMSDecoderDataStr NSSCMSDecoderData; - -static void nss_cms_decoder_update_filter (void *arg, const char *data, - unsigned long len, int depth, SEC_ASN1EncodingPart data_kind); -static SECStatus nss_cms_before_data(NSSCMSDecoderContext *p7dcx); -static SECStatus nss_cms_after_data(NSSCMSDecoderContext *p7dcx); -static SECStatus nss_cms_after_end(NSSCMSDecoderContext *p7dcx); -static void nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx, - const unsigned char *data, unsigned long len, PRBool final); -static NSSCMSDecoderData *nss_cms_create_decoder_data(PRArenaPool *poolp); - -extern const SEC_ASN1Template NSSCMSMessageTemplate[]; - -static NSSCMSDecoderData * -nss_cms_create_decoder_data(PRArenaPool *poolp) -{ - NSSCMSDecoderData *decoderData = NULL; - - decoderData = (NSSCMSDecoderData *) - PORT_ArenaAlloc(poolp,sizeof(NSSCMSDecoderData)); - if (!decoderData) { - return NULL; - } - decoderData->data.data = NULL; - decoderData->data.len = 0; - decoderData->totalBufferSize = 0; - return decoderData; -} - -/* - * nss_cms_decoder_notify - - * this is the driver of the decoding process. It gets called by the ASN.1 - * decoder before and after an object is decoded. - * at various points in the decoding process, we intercept to set up and do - * further processing. - */ -static void -nss_cms_decoder_notify(void *arg, PRBool before, void *dest, int depth) -{ - NSSCMSDecoderContext *p7dcx; - NSSCMSContentInfo *rootcinfo, *cinfo; - PRBool after = !before; - - p7dcx = (NSSCMSDecoderContext *)arg; - rootcinfo = &(p7dcx->cmsg->contentInfo); - - /* XXX error handling: need to set p7dcx->error */ - -#ifdef CMSDEBUG - fprintf(stderr, "%6.6s, dest = 0x%08x, depth = %d\n", before ? "before" : "after", dest, depth); -#endif - - /* so what are we working on right now? */ - switch (p7dcx->type) { - case SEC_OID_UNKNOWN: - /* - * right now, we are still decoding the OUTER (root) cinfo - * As soon as we know the inner content type, set up the info, - * but NO inner decoder or filter. The root decoder handles the first - * level children by itself - only for encapsulated contents (which - * are encoded as DER inside of an OCTET STRING) we need to set up a - * child decoder... - */ - if (after && dest == &(rootcinfo->contentType)) { - p7dcx->type = NSS_CMSContentInfo_GetContentTypeTag(rootcinfo); - p7dcx->content = rootcinfo->content; - /* is this ready already ? need to alloc? */ - /* XXX yes we need to alloc -- continue here */ - } - break; - case SEC_OID_PKCS7_DATA: - /* this can only happen if the outermost cinfo has DATA in it */ - /* otherwise, we handle this type implicitely in the inner decoders */ - - if (before && dest == &(rootcinfo->content)) { - /* cause the filter to put the data in the right place... - ** We want the ASN.1 decoder to deliver the decoded bytes to us - ** from now on - */ - SEC_ASN1DecoderSetFilterProc(p7dcx->dcx, - nss_cms_decoder_update_filter, - p7dcx, - (PRBool)(p7dcx->cb != NULL)); - break; - } - - if (after && dest == &(rootcinfo->content.data)) { - /* remove the filter */ - SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); - } - break; - - case SEC_OID_PKCS7_SIGNED_DATA: - case SEC_OID_PKCS7_ENVELOPED_DATA: - case SEC_OID_PKCS7_DIGESTED_DATA: - case SEC_OID_PKCS7_ENCRYPTED_DATA: - - if (before && dest == &(rootcinfo->content)) - break; /* we're not there yet */ - - if (p7dcx->content.pointer == NULL) - p7dcx->content = rootcinfo->content; - - /* get this data type's inner contentInfo */ - cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer, - p7dcx->type); - - if (before && dest == &(cinfo->contentType)) { - /* at this point, set up the &%$&$ back pointer */ - /* we cannot do it later, because the content itself is optional! */ - /* please give me C++ */ - switch (p7dcx->type) { - case SEC_OID_PKCS7_SIGNED_DATA: - p7dcx->content.signedData->cmsg = p7dcx->cmsg; - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - p7dcx->content.digestedData->cmsg = p7dcx->cmsg; - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - p7dcx->content.envelopedData->cmsg = p7dcx->cmsg; - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - p7dcx->content.encryptedData->cmsg = p7dcx->cmsg; - break; - default: - PORT_Assert(0); - break; - } - } - - if (before && dest == &(cinfo->rawContent)) { - /* we want the ASN.1 decoder to deliver the decoded bytes to us - ** from now on - */ - SEC_ASN1DecoderSetFilterProc(p7dcx->dcx, - nss_cms_decoder_update_filter, - p7dcx, (PRBool)(p7dcx->cb != NULL)); - - - /* we're right in front of the data */ - if (nss_cms_before_data(p7dcx) != SECSuccess) { - SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); - /* stop all processing */ - p7dcx->error = PORT_GetError(); - } - } - if (after && dest == &(cinfo->rawContent)) { - /* we're right after of the data */ - if (nss_cms_after_data(p7dcx) != SECSuccess) - p7dcx->error = PORT_GetError(); - - /* we don't need to see the contents anymore */ - SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); - } - break; - -#if 0 /* NIH */ - case SEC_OID_PKCS7_AUTHENTICATED_DATA: -#endif - default: - /* unsupported or unknown message type - fail gracefully */ - p7dcx->error = SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE; - break; - } -} - -/* - * nss_cms_before_data - set up the current encoder to receive data - */ -static SECStatus -nss_cms_before_data(NSSCMSDecoderContext *p7dcx) -{ - SECStatus rv; - SECOidTag childtype; - PLArenaPool *poolp; - NSSCMSDecoderContext *childp7dcx; - NSSCMSContentInfo *cinfo; - const SEC_ASN1Template *template; - void *mark = NULL; - size_t size; - - poolp = p7dcx->cmsg->poolp; - - /* call _Decode_BeforeData handlers */ - switch (p7dcx->type) { - case SEC_OID_PKCS7_SIGNED_DATA: - /* we're decoding a signedData, so set up the digests */ - rv = NSS_CMSSignedData_Decode_BeforeData(p7dcx->content.signedData); - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - /* we're encoding a digestedData, so set up the digest */ - rv = NSS_CMSDigestedData_Decode_BeforeData(p7dcx->content.digestedData); - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - rv = NSS_CMSEnvelopedData_Decode_BeforeData( - p7dcx->content.envelopedData); - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - rv = NSS_CMSEncryptedData_Decode_BeforeData( - p7dcx->content.encryptedData); - break; - default: - return SECFailure; - } - if (rv != SECSuccess) - return SECFailure; - - /* ok, now we have a pointer to cinfo */ - /* find out what kind of data is encapsulated */ - - cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer, p7dcx->type); - childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo); - - if (childtype == SEC_OID_PKCS7_DATA) { - cinfo->content.pointer = (void *) nss_cms_create_decoder_data(poolp); - if (cinfo->content.pointer == NULL) - /* set memory error */ - return SECFailure; - - p7dcx->childp7dcx = NULL; - return SECSuccess; - } - - /* set up inner decoder */ - - if ((template = NSS_CMSUtil_GetTemplateByTypeTag(childtype)) == NULL) - return SECFailure; - - childp7dcx = PORT_ZNew(NSSCMSDecoderContext); - if (childp7dcx == NULL) - return SECFailure; - - mark = PORT_ArenaMark(poolp); - - /* allocate space for the stuff we're creating */ - size = NSS_CMSUtil_GetSizeByTypeTag(childtype); - childp7dcx->content.pointer = (void *)PORT_ArenaZAlloc(poolp, size); - if (childp7dcx->content.pointer == NULL) - goto loser; - - /* start the child decoder */ - childp7dcx->dcx = SEC_ASN1DecoderStart(poolp, childp7dcx->content.pointer, - template); - if (childp7dcx->dcx == NULL) - goto loser; - - /* the new decoder needs to notify, too */ - SEC_ASN1DecoderSetNotifyProc(childp7dcx->dcx, nss_cms_decoder_notify, - childp7dcx); - - /* tell the parent decoder that it needs to feed us the content data */ - p7dcx->childp7dcx = childp7dcx; - - childp7dcx->type = childtype; /* our type */ - - childp7dcx->cmsg = p7dcx->cmsg; /* backpointer to root message */ - - /* should the child decoder encounter real data, - ** it must give it to the caller - */ - childp7dcx->cb = p7dcx->cb; - childp7dcx->cb_arg = p7dcx->cb_arg; - - /* now set up the parent to hand decoded data to the next level decoder */ - p7dcx->cb = (NSSCMSContentCallback)NSS_CMSDecoder_Update; - p7dcx->cb_arg = childp7dcx; - - PORT_ArenaUnmark(poolp, mark); - - return SECSuccess; - -loser: - if (mark) - PORT_ArenaRelease(poolp, mark); - if (childp7dcx) - PORT_Free(childp7dcx); - p7dcx->childp7dcx = NULL; - return SECFailure; -} - -static SECStatus -nss_cms_after_data(NSSCMSDecoderContext *p7dcx) -{ - NSSCMSDecoderContext *childp7dcx; - SECStatus rv = SECFailure; - - /* Handle last block. This is necessary to flush out the last bytes - * of a possibly incomplete block */ - nss_cms_decoder_work_data(p7dcx, NULL, 0, PR_TRUE); - - /* finish any "inner" decoders - there's no more data coming... */ - if (p7dcx->childp7dcx != NULL) { - childp7dcx = p7dcx->childp7dcx; - if (childp7dcx->dcx != NULL) { - if (SEC_ASN1DecoderFinish(childp7dcx->dcx) != SECSuccess) { - /* do what? free content? */ - rv = SECFailure; - } else { - rv = nss_cms_after_end(childp7dcx); - } - if (rv != SECSuccess) - goto done; - } - PORT_Free(p7dcx->childp7dcx); - p7dcx->childp7dcx = NULL; - } - - switch (p7dcx->type) { - case SEC_OID_PKCS7_SIGNED_DATA: - /* this will finish the digests and verify */ - rv = NSS_CMSSignedData_Decode_AfterData(p7dcx->content.signedData); - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - rv = NSS_CMSEnvelopedData_Decode_AfterData( - p7dcx->content.envelopedData); - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - rv = NSS_CMSDigestedData_Decode_AfterData( - p7dcx->content.digestedData); - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - rv = NSS_CMSEncryptedData_Decode_AfterData( - p7dcx->content.encryptedData); - break; - case SEC_OID_PKCS7_DATA: - /* do nothing */ - break; - default: - rv = SECFailure; - break; - } -done: - return rv; -} - -static SECStatus -nss_cms_after_end(NSSCMSDecoderContext *p7dcx) -{ - SECStatus rv = SECSuccess; - - switch (p7dcx->type) { - case SEC_OID_PKCS7_SIGNED_DATA: - if (p7dcx->content.signedData) - rv = NSS_CMSSignedData_Decode_AfterEnd(p7dcx->content.signedData); - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - if (p7dcx->content.envelopedData) - rv = NSS_CMSEnvelopedData_Decode_AfterEnd( - p7dcx->content.envelopedData); - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - if (p7dcx->content.digestedData) - rv = NSS_CMSDigestedData_Decode_AfterEnd( - p7dcx->content.digestedData); - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - if (p7dcx->content.encryptedData) - rv = NSS_CMSEncryptedData_Decode_AfterEnd( - p7dcx->content.encryptedData); - break; - case SEC_OID_PKCS7_DATA: - break; - default: - rv = SECFailure; /* we should not have got that far... */ - break; - } - return rv; -} - -/* - * nss_cms_decoder_work_data - handle decoded data bytes. - * - * This function either decrypts the data if needed, and/or calculates digests - * on it, then either stores it or passes it on to the next level decoder. - */ -static void -nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx, - const unsigned char *data, unsigned long len, - PRBool final) -{ - NSSCMSContentInfo *cinfo; - unsigned char *buf = NULL; - unsigned char *dest; - unsigned int offset; - SECStatus rv; - - /* - * We should really have data to process, or we should be trying - * to finish/flush the last block. (This is an overly paranoid - * check since all callers are in this file and simple inspection - * proves they do it right. But it could find a bug in future - * modifications/development, that is why it is here.) - */ - PORT_Assert ((data != NULL && len) || final); - - cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer, p7dcx->type); - - if (cinfo->ciphcx != NULL) { - /* - * we are decrypting. - * - * XXX If we get an error, we do not want to do the digest or callback, - * but we want to keep decoding. Or maybe we want to stop decoding - * altogether if there is a callback, because obviously we are not - * sending the data back and they want to know that. - */ - - unsigned int outlen = 0; /* length of decrypted data */ - unsigned int buflen; /* length available for decrypted data */ - - /* find out about the length of decrypted data */ - buflen = NSS_CMSCipherContext_DecryptLength(cinfo->ciphcx, len, final); - - /* - * it might happen that we did not provide enough data for a full - * block (decryption unit), and that there is no output available - */ - - /* no output available, AND no input? */ - if (buflen == 0 && len == 0) - goto loser; /* bail out */ - - /* - * have inner decoder: pass the data on (means inner content type is NOT data) - * no inner decoder: we have DATA in here: either call callback or store - */ - if (buflen != 0) { - /* there will be some output - need to make room for it */ - /* allocate buffer from the heap */ - buf = (unsigned char *)PORT_Alloc(buflen); - if (buf == NULL) { - p7dcx->error = SEC_ERROR_NO_MEMORY; - goto loser; - } - } - - /* - * decrypt incoming data - * buf can still be NULL here (and buflen == 0) here if we don't expect - * any output (see above), but we still need to call NSS_CMSCipherContext_Decrypt to - * keep track of incoming data - */ - rv = NSS_CMSCipherContext_Decrypt(cinfo->ciphcx, buf, &outlen, buflen, - data, len, final); - if (rv != SECSuccess) { - p7dcx->error = PORT_GetError(); - goto loser; - } - - PORT_Assert (final || outlen == buflen); - - /* swap decrypted data in */ - data = buf; - len = outlen; - } - - if (len == 0) - goto done; /* nothing more to do */ - - /* - * Update the running digests with plaintext bytes (if we need to). - */ - if (cinfo->digcx) - NSS_CMSDigestContext_Update(cinfo->digcx, data, len); - - /* at this point, we have the plain decoded & decrypted data - ** which is either more encoded DER (which we need to hand to the child - ** decoder) or data we need to hand back to our caller - */ - - /* pass the content back to our caller or */ - /* feed our freshly decrypted and decoded data into child decoder */ - if (p7dcx->cb != NULL) { - (*p7dcx->cb)(p7dcx->cb_arg, (const char *)data, len); - } -#if 1 - else -#endif - if (NSS_CMSContentInfo_GetContentTypeTag(cinfo) == SEC_OID_PKCS7_DATA) { - /* store it in "inner" data item as well */ - /* find the DATA item in the encapsulated cinfo and store it there */ - NSSCMSDecoderData *decoderData = - (NSSCMSDecoderData *)cinfo->content.pointer; - SECItem *dataItem = &decoderData->data; - - offset = dataItem->len; - if (dataItem->len+len > decoderData->totalBufferSize) { - int needLen = (dataItem->len+len) * 2; - dest = (unsigned char *) - PORT_ArenaAlloc(p7dcx->cmsg->poolp, needLen); - if (dest == NULL) { - p7dcx->error = SEC_ERROR_NO_MEMORY; - goto loser; - } - - if (dataItem->len) { - PORT_Memcpy(dest, dataItem->data, dataItem->len); - } - decoderData->totalBufferSize = needLen; - dataItem->data = dest; - } - - /* copy it in */ - PORT_Memcpy(dataItem->data + offset, data, len); - dataItem->len += len; - } - -done: -loser: - if (buf) - PORT_Free (buf); -} - -/* - * nss_cms_decoder_update_filter - process ASN.1 data - * - * once we have set up a filter in nss_cms_decoder_notify(), - * all data processed by the ASN.1 decoder is also passed through here. - * we pass the content bytes (as opposed to length and tag bytes) on to - * nss_cms_decoder_work_data(). - */ -static void -nss_cms_decoder_update_filter (void *arg, const char *data, unsigned long len, - int depth, SEC_ASN1EncodingPart data_kind) -{ - NSSCMSDecoderContext *p7dcx; - - PORT_Assert (len); /* paranoia */ - if (len == 0) - return; - - p7dcx = (NSSCMSDecoderContext*)arg; - - p7dcx->saw_contents = PR_TRUE; - - /* pass on the content bytes only */ - if (data_kind == SEC_ASN1_Contents) - nss_cms_decoder_work_data(p7dcx, (const unsigned char *) data, len, - PR_FALSE); -} - -/* - * NSS_CMSDecoder_Start - set up decoding of a DER-encoded CMS message - * - * "poolp" - pointer to arena for message, or NULL if new pool should be created - * "cb", "cb_arg" - callback function and argument for delivery of inner content - * "pwfn", pwfn_arg" - callback function for getting token password - * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData - */ -NSSCMSDecoderContext * -NSS_CMSDecoder_Start(PRArenaPool *poolp, - NSSCMSContentCallback cb, void *cb_arg, - PK11PasswordFunc pwfn, void *pwfn_arg, - NSSCMSGetDecryptKeyCallback decrypt_key_cb, - void *decrypt_key_cb_arg) -{ - NSSCMSDecoderContext *p7dcx; - NSSCMSMessage *cmsg; - - cmsg = NSS_CMSMessage_Create(poolp); - if (cmsg == NULL) - return NULL; - - NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb, - decrypt_key_cb_arg, NULL, NULL); - - p7dcx = PORT_ZNew(NSSCMSDecoderContext); - if (p7dcx == NULL) { - NSS_CMSMessage_Destroy(cmsg); - return NULL; - } - - p7dcx->dcx = SEC_ASN1DecoderStart(cmsg->poolp, cmsg, NSSCMSMessageTemplate); - if (p7dcx->dcx == NULL) { - PORT_Free (p7dcx); - NSS_CMSMessage_Destroy(cmsg); - return NULL; - } - - SEC_ASN1DecoderSetNotifyProc (p7dcx->dcx, nss_cms_decoder_notify, p7dcx); - - p7dcx->cmsg = cmsg; - p7dcx->type = SEC_OID_UNKNOWN; - - p7dcx->cb = cb; - p7dcx->cb_arg = cb_arg; - - return p7dcx; -} - -/* - * NSS_CMSDecoder_Update - feed DER-encoded data to decoder - */ -SECStatus -NSS_CMSDecoder_Update(NSSCMSDecoderContext *p7dcx, const char *buf, - unsigned long len) -{ - SECStatus rv; - if (p7dcx->dcx != NULL && p7dcx->error == 0) { - /* if error is set already, don't bother */ - rv = SEC_ASN1DecoderUpdate(p7dcx->dcx, buf, len); - if (rv != SECSuccess) { - p7dcx->error = PORT_GetError(); - PORT_Assert (p7dcx->error); - if (p7dcx->error == 0) - p7dcx->error = -1; - } - } - - if (p7dcx->error == 0) - return SECSuccess; - - /* there has been a problem, let's finish the decoder */ - if (p7dcx->dcx != NULL) { - (void) SEC_ASN1DecoderFinish (p7dcx->dcx); - p7dcx->dcx = NULL; - } - PORT_SetError (p7dcx->error); - - return SECFailure; -} - -/* - * NSS_CMSDecoder_Cancel - stop decoding in case of error - */ -void -NSS_CMSDecoder_Cancel(NSSCMSDecoderContext *p7dcx) -{ - /* XXXX what about inner decoders? running digests? decryption? */ - /* XXXX there's a leak here! */ - NSS_CMSMessage_Destroy(p7dcx->cmsg); - (void)SEC_ASN1DecoderFinish(p7dcx->dcx); - PORT_Free(p7dcx); -} - -/* - * NSS_CMSDecoder_Finish - mark the end of inner content and finish decoding - */ -NSSCMSMessage * -NSS_CMSDecoder_Finish(NSSCMSDecoderContext *p7dcx) -{ - NSSCMSMessage *cmsg; - - cmsg = p7dcx->cmsg; - - if (p7dcx->dcx == NULL || - SEC_ASN1DecoderFinish(p7dcx->dcx) != SECSuccess || - nss_cms_after_end(p7dcx) != SECSuccess) - { - NSS_CMSMessage_Destroy(cmsg); /* get rid of pool if it's ours */ - cmsg = NULL; - } - - PORT_Free(p7dcx); - return cmsg; -} - -NSSCMSMessage * -NSS_CMSMessage_CreateFromDER(SECItem *DERmessage, - NSSCMSContentCallback cb, void *cb_arg, - PK11PasswordFunc pwfn, void *pwfn_arg, - NSSCMSGetDecryptKeyCallback decrypt_key_cb, - void *decrypt_key_cb_arg) -{ - NSSCMSDecoderContext *p7dcx; - - /* first arg(poolp) == NULL => create our own pool */ - p7dcx = NSS_CMSDecoder_Start(NULL, cb, cb_arg, pwfn, pwfn_arg, - decrypt_key_cb, decrypt_key_cb_arg); - NSS_CMSDecoder_Update(p7dcx, (char *)DERmessage->data, DERmessage->len); - return NSS_CMSDecoder_Finish(p7dcx); -} - diff --git a/security/nss/lib/smime/cmsdigdata.c b/security/nss/lib/smime/cmsdigdata.c deleted file mode 100644 index e3eb4159d..000000000 --- a/security/nss/lib/smime/cmsdigdata.c +++ /dev/null @@ -1,231 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS digestedData methods. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "secitem.h" -#include "secasn1.h" -#include "secoid.h" -#include "secerr.h" - -/* - * NSS_CMSDigestedData_Create - create a digestedData object (presumably for encoding) - * - * version will be set by NSS_CMSDigestedData_Encode_BeforeStart - * digestAlg is passed as parameter - * contentInfo must be filled by the user - * digest will be calculated while encoding - */ -NSSCMSDigestedData * -NSS_CMSDigestedData_Create(NSSCMSMessage *cmsg, SECAlgorithmID *digestalg) -{ - void *mark; - NSSCMSDigestedData *digd; - PLArenaPool *poolp; - - poolp = cmsg->poolp; - - mark = PORT_ArenaMark(poolp); - - digd = (NSSCMSDigestedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSDigestedData)); - if (digd == NULL) - goto loser; - - digd->cmsg = cmsg; - - if (SECOID_CopyAlgorithmID (poolp, &(digd->digestAlg), digestalg) != SECSuccess) - goto loser; - - PORT_ArenaUnmark(poolp, mark); - return digd; - -loser: - PORT_ArenaRelease(poolp, mark); - return NULL; -} - -/* - * NSS_CMSDigestedData_Destroy - destroy a digestedData object - */ -void -NSS_CMSDigestedData_Destroy(NSSCMSDigestedData *digd) -{ - /* everything's in a pool, so don't worry about the storage */ - NSS_CMSContentInfo_Destroy(&(digd->contentInfo)); - return; -} - -/* - * NSS_CMSDigestedData_GetContentInfo - return pointer to digestedData object's contentInfo - */ -NSSCMSContentInfo * -NSS_CMSDigestedData_GetContentInfo(NSSCMSDigestedData *digd) -{ - return &(digd->contentInfo); -} - -/* - * NSS_CMSDigestedData_Encode_BeforeStart - do all the necessary things to a DigestedData - * before encoding begins. - * - * In particular: - * - set the right version number. The contentInfo's content type must be set up already. - */ -SECStatus -NSS_CMSDigestedData_Encode_BeforeStart(NSSCMSDigestedData *digd) -{ - unsigned long version; - SECItem *dummy; - - version = NSS_CMS_DIGESTED_DATA_VERSION_DATA; - if (NSS_CMSContentInfo_GetContentTypeTag(&(digd->contentInfo)) != SEC_OID_PKCS7_DATA) - version = NSS_CMS_DIGESTED_DATA_VERSION_ENCAP; - - dummy = SEC_ASN1EncodeInteger(digd->cmsg->poolp, &(digd->version), version); - return (dummy == NULL) ? SECFailure : SECSuccess; -} - -/* - * NSS_CMSDigestedData_Encode_BeforeData - do all the necessary things to a DigestedData - * before the encapsulated data is passed through the encoder. - * - * In detail: - * - set up the digests if necessary - */ -SECStatus -NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData *digd) -{ - /* set up the digests */ - if (digd->digestAlg.algorithm.len != 0 && digd->digest.len == 0) { - /* if digest is already there, do nothing */ - digd->contentInfo.digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg)); - if (digd->contentInfo.digcx == NULL) - return SECFailure; - } - return SECSuccess; -} - -/* - * NSS_CMSDigestedData_Encode_AfterData - do all the necessary things to a DigestedData - * after all the encapsulated data was passed through the encoder. - * - * In detail: - * - finish the digests - */ -SECStatus -NSS_CMSDigestedData_Encode_AfterData(NSSCMSDigestedData *digd) -{ - SECStatus rv = SECSuccess; - /* did we have digest calculation going on? */ - if (digd->contentInfo.digcx) { - rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.digcx, - digd->cmsg->poolp, - &(digd->digest)); - /* error has been set by NSS_CMSDigestContext_FinishSingle */ - digd->contentInfo.digcx = NULL; - } - - return rv; -} - -/* - * NSS_CMSDigestedData_Decode_BeforeData - do all the necessary things to a DigestedData - * before the encapsulated data is passed through the encoder. - * - * In detail: - * - set up the digests if necessary - */ -SECStatus -NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData *digd) -{ - /* is there a digest algorithm yet? */ - if (digd->digestAlg.algorithm.len == 0) - return SECFailure; - - digd->contentInfo.digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg)); - if (digd->contentInfo.digcx == NULL) - return SECFailure; - - return SECSuccess; -} - -/* - * NSS_CMSDigestedData_Decode_AfterData - do all the necessary things to a DigestedData - * after all the encapsulated data was passed through the encoder. - * - * In detail: - * - finish the digests - */ -SECStatus -NSS_CMSDigestedData_Decode_AfterData(NSSCMSDigestedData *digd) -{ - SECStatus rv = SECSuccess; - /* did we have digest calculation going on? */ - if (digd->contentInfo.digcx) { - rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.digcx, - digd->cmsg->poolp, - &(digd->cdigest)); - /* error has been set by NSS_CMSDigestContext_FinishSingle */ - digd->contentInfo.digcx = NULL; - } - - return rv; -} - -/* - * NSS_CMSDigestedData_Decode_AfterEnd - finalize a digestedData. - * - * In detail: - * - check the digests for equality - */ -SECStatus -NSS_CMSDigestedData_Decode_AfterEnd(NSSCMSDigestedData *digd) -{ - /* did we have digest calculation going on? */ - if (digd->cdigest.len != 0) { - /* XXX comparision btw digest & cdigest */ - /* XXX set status */ - /* TODO!!!! */ - } - - return SECSuccess; -} diff --git a/security/nss/lib/smime/cmsdigest.c b/security/nss/lib/smime/cmsdigest.c deleted file mode 100644 index e0e923a77..000000000 --- a/security/nss/lib/smime/cmsdigest.c +++ /dev/null @@ -1,294 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS digesting. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "cert.h" -#include "key.h" -#include "secitem.h" -#include "secoid.h" -#include "pk11func.h" -#include "prtime.h" -#include "secerr.h" - -/* #define CMS_FIND_LEAK_MULTIPLE 1 */ -#ifdef CMS_FIND_LEAK_MULTIPLE -static int stop_on_err = 1; -static int global_num_digests = 0; -#endif - -struct digestPairStr { - const SECHashObject * digobj; - void * digcx; -}; -typedef struct digestPairStr digestPair; - -struct NSSCMSDigestContextStr { - PRBool saw_contents; - PLArenaPool * pool; - int digcnt; - digestPair * digPairs; -}; - - -/* - * NSS_CMSDigestContext_StartMultiple - start digest calculation using all the - * digest algorithms in "digestalgs" in parallel. - */ -NSSCMSDigestContext * -NSS_CMSDigestContext_StartMultiple(SECAlgorithmID **digestalgs) -{ - PLArenaPool * pool; - NSSCMSDigestContext *cmsdigcx; - int digcnt; - int i; - -#ifdef CMS_FIND_LEAK_MULTIPLE - PORT_Assert(global_num_digests == 0 || !stop_on_err); -#endif - - digcnt = (digestalgs == NULL) ? 0 : NSS_CMSArray_Count((void **)digestalgs); - /* It's OK if digcnt is zero. We have to allow this for "certs only" - ** messages. - */ - pool = PORT_NewArena(2048); - if (!pool) - return NULL; - - cmsdigcx = PORT_ArenaNew(pool, NSSCMSDigestContext); - if (cmsdigcx == NULL) - goto loser; - - cmsdigcx->saw_contents = PR_FALSE; - cmsdigcx->pool = pool; - cmsdigcx->digcnt = digcnt; - - cmsdigcx->digPairs = PORT_ArenaZNewArray(pool, digestPair, digcnt); - if (cmsdigcx->digPairs == NULL) { - goto loser; - } - - /* - * Create a digest object context for each algorithm. - */ - for (i = 0; i < digcnt; i++) { - const SECHashObject *digobj; - void *digcx; - - digobj = NSS_CMSUtil_GetHashObjByAlgID(digestalgs[i]); - /* - * Skip any algorithm we do not even recognize; obviously, - * this could be a problem, but if it is critical then the - * result will just be that the signature does not verify. - * We do not necessarily want to error out here, because - * the particular algorithm may not actually be important, - * but we cannot know that until later. - */ - if (digobj == NULL) - continue; - - digcx = (*digobj->create)(); - if (digcx != NULL) { - (*digobj->begin) (digcx); - cmsdigcx->digPairs[i].digobj = digobj; - cmsdigcx->digPairs[i].digcx = digcx; -#ifdef CMS_FIND_LEAK_MULTIPLE - global_num_digests++; -#endif - } - } - return cmsdigcx; - -loser: - /* no digest objects have been created, or need to be destroyed. */ - if (pool) { - PORT_FreeArena(pool, PR_FALSE); - } - return NULL; -} - -/* - * NSS_CMSDigestContext_StartSingle - same as - * NSS_CMSDigestContext_StartMultiple, but only one algorithm. - */ -NSSCMSDigestContext * -NSS_CMSDigestContext_StartSingle(SECAlgorithmID *digestalg) -{ - SECAlgorithmID *digestalgs[] = { NULL, NULL }; /* fake array */ - - digestalgs[0] = digestalg; - return NSS_CMSDigestContext_StartMultiple(digestalgs); -} - -/* - * NSS_CMSDigestContext_Update - feed more data into the digest machine - */ -void -NSS_CMSDigestContext_Update(NSSCMSDigestContext *cmsdigcx, - const unsigned char *data, int len) -{ - int i; - digestPair *pair = cmsdigcx->digPairs; - - cmsdigcx->saw_contents = PR_TRUE; - - for (i = 0; i < cmsdigcx->digcnt; i++, pair++) { - if (pair->digcx) { - (*pair->digobj->update)(pair->digcx, data, len); - } - } -} - -/* - * NSS_CMSDigestContext_Cancel - cancel digesting operation - */ -void -NSS_CMSDigestContext_Cancel(NSSCMSDigestContext *cmsdigcx) -{ - int i; - digestPair *pair = cmsdigcx->digPairs; - - for (i = 0; i < cmsdigcx->digcnt; i++, pair++) { - if (pair->digcx) { - (*pair->digobj->destroy)(pair->digcx, PR_TRUE); -#ifdef CMS_FIND_LEAK_MULTIPLE - --global_num_digests; -#endif - } - } -#ifdef CMS_FIND_LEAK_MULTIPLE - PORT_Assert(global_num_digests == 0 || !stop_on_err); -#endif - PORT_FreeArena(cmsdigcx->pool, PR_FALSE); -} - -/* - * NSS_CMSDigestContext_FinishMultiple - finish the digests and put them - * into an array of SECItems (allocated on poolp) - */ -SECStatus -NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx, - PLArenaPool *poolp, - SECItem ***digestsp) -{ - SECItem ** digests = NULL; - digestPair *pair; - void * mark; - int i; - SECStatus rv; - - /* no contents? do not finish digests */ - if (digestsp == NULL || !cmsdigcx->saw_contents) { - rv = SECSuccess; - goto cleanup; - } - - mark = PORT_ArenaMark (poolp); - - /* allocate digest array & SECItems on arena */ - digests = PORT_ArenaNewArray( poolp, SECItem *, cmsdigcx->digcnt + 1); - - rv = ((digests == NULL) ? SECFailure : SECSuccess); - pair = cmsdigcx->digPairs; - for (i = 0; rv == SECSuccess && i < cmsdigcx->digcnt; i++, pair++) { - SECItem digest; - unsigned char hash[HASH_LENGTH_MAX]; - - if (!pair->digcx) { - digests[i] = NULL; - continue; - } - - digest.type = siBuffer; - digest.data = hash; - digest.len = pair->digobj->length; - (* pair->digobj->end)(pair->digcx, hash, &digest.len, digest.len); - digests[i] = SECITEM_ArenaDupItem(poolp, &digest); - if (!digests[i]) { - rv = SECFailure; - } - } - digests[i] = NULL; - if (rv == SECSuccess) { - PORT_ArenaUnmark(poolp, mark); - } else - PORT_ArenaRelease(poolp, mark); - -cleanup: - NSS_CMSDigestContext_Cancel(cmsdigcx); - /* Don't change the caller's digests pointer if we have no digests. - ** NSS_CMSSignedData_Encode_AfterData depends on this behavior. - */ - if (rv == SECSuccess && digestsp && digests) { - *digestsp = digests; - } - return rv; -} - -/* - * NSS_CMSDigestContext_FinishSingle - same as - * NSS_CMSDigestContext_FinishMultiple, but for one digest. - */ -SECStatus -NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx, - PLArenaPool *poolp, - SECItem *digest) -{ - SECStatus rv = SECFailure; - SECItem **dp; - PLArenaPool *arena = NULL; - - if ((arena = PORT_NewArena(1024)) == NULL) - goto loser; - - /* get the digests into arena, then copy the first digest into poolp */ - rv = NSS_CMSDigestContext_FinishMultiple(cmsdigcx, arena, &dp); - if (rv == SECSuccess) { - /* now copy it into poolp */ - rv = SECITEM_CopyItem(poolp, digest, dp[0]); - } -loser: - if (arena) - PORT_FreeArena(arena, PR_FALSE); - - return rv; -} diff --git a/security/nss/lib/smime/cmsencdata.c b/security/nss/lib/smime/cmsencdata.c deleted file mode 100644 index 0bcbb680a..000000000 --- a/security/nss/lib/smime/cmsencdata.c +++ /dev/null @@ -1,280 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS encryptedData methods. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "key.h" -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "pk11func.h" -#include "prtime.h" -#include "secerr.h" -#include "secpkcs5.h" - -/* - * NSS_CMSEncryptedData_Create - create an empty encryptedData object. - * - * "algorithm" specifies the bulk encryption algorithm to use. - * "keysize" is the key size. - * - * An error results in a return value of NULL and an error set. - * (Retrieve specific errors via PORT_GetError()/XP_GetError().) - */ -NSSCMSEncryptedData * -NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize) -{ - void *mark; - NSSCMSEncryptedData *encd; - PLArenaPool *poolp; - SECAlgorithmID *pbe_algid; - SECStatus rv; - - poolp = cmsg->poolp; - - mark = PORT_ArenaMark(poolp); - - encd = (NSSCMSEncryptedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSEncryptedData)); - if (encd == NULL) - goto loser; - - encd->cmsg = cmsg; - - /* version is set in NSS_CMSEncryptedData_Encode_BeforeStart() */ - - switch (algorithm) { - /* XXX hmmm... hardcoded algorithms? */ - case SEC_OID_RC2_CBC: - case SEC_OID_DES_EDE3_CBC: - case SEC_OID_DES_CBC: - rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(encd->contentInfo), algorithm, NULL, keysize); - break; - default: - /* Assume password-based-encryption. At least, try that. */ - pbe_algid = PK11_CreatePBEAlgorithmID(algorithm, 1, NULL); - if (pbe_algid == NULL) { - rv = SECFailure; - break; - } - rv = NSS_CMSContentInfo_SetContentEncAlgID(poolp, &(encd->contentInfo), pbe_algid, keysize); - SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE); - break; - } - if (rv != SECSuccess) - goto loser; - - PORT_ArenaUnmark(poolp, mark); - return encd; - -loser: - PORT_ArenaRelease(poolp, mark); - return NULL; -} - -/* - * NSS_CMSEncryptedData_Destroy - destroy an encryptedData object - */ -void -NSS_CMSEncryptedData_Destroy(NSSCMSEncryptedData *encd) -{ - /* everything's in a pool, so don't worry about the storage */ - NSS_CMSContentInfo_Destroy(&(encd->contentInfo)); - return; -} - -/* - * NSS_CMSEncryptedData_GetContentInfo - return pointer to encryptedData object's contentInfo - */ -NSSCMSContentInfo * -NSS_CMSEncryptedData_GetContentInfo(NSSCMSEncryptedData *encd) -{ - return &(encd->contentInfo); -} - -/* - * NSS_CMSEncryptedData_Encode_BeforeStart - do all the necessary things to a EncryptedData - * before encoding begins. - * - * In particular: - * - set the correct version value. - * - get the encryption key - */ -SECStatus -NSS_CMSEncryptedData_Encode_BeforeStart(NSSCMSEncryptedData *encd) -{ - int version; - PK11SymKey *bulkkey = NULL; - SECItem *dummy; - NSSCMSContentInfo *cinfo = &(encd->contentInfo); - - if (NSS_CMSArray_IsEmpty((void **)encd->unprotectedAttr)) - version = NSS_CMS_ENCRYPTED_DATA_VERSION; - else - version = NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR; - - dummy = SEC_ASN1EncodeInteger (encd->cmsg->poolp, &(encd->version), version); - if (dummy == NULL) - return SECFailure; - - /* now get content encryption key (bulk key) by using our cmsg callback */ - if (encd->cmsg->decrypt_key_cb) - bulkkey = (*encd->cmsg->decrypt_key_cb)(encd->cmsg->decrypt_key_cb_arg, - NSS_CMSContentInfo_GetContentEncAlg(cinfo)); - if (bulkkey == NULL) - return SECFailure; - - /* store the bulk key in the contentInfo so that the encoder can find it */ - NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey); - PK11_FreeSymKey (bulkkey); - - return SECSuccess; -} - -/* - * NSS_CMSEncryptedData_Encode_BeforeData - set up encryption - */ -SECStatus -NSS_CMSEncryptedData_Encode_BeforeData(NSSCMSEncryptedData *encd) -{ - NSSCMSContentInfo *cinfo; - PK11SymKey *bulkkey; - SECAlgorithmID *algid; - - cinfo = &(encd->contentInfo); - - /* find bulkkey and algorithm - must have been set by NSS_CMSEncryptedData_Encode_BeforeStart */ - bulkkey = NSS_CMSContentInfo_GetBulkKey(cinfo); - if (bulkkey == NULL) - return SECFailure; - algid = NSS_CMSContentInfo_GetContentEncAlg(cinfo); - if (algid == NULL) - return SECFailure; - - /* this may modify algid (with IVs generated in a token). - * it is therefore essential that algid is a pointer to the "real" contentEncAlg, - * not just to a copy */ - cinfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(encd->cmsg->poolp, bulkkey, algid); - PK11_FreeSymKey(bulkkey); - if (cinfo->ciphcx == NULL) - return SECFailure; - - return SECSuccess; -} - -/* - * NSS_CMSEncryptedData_Encode_AfterData - finalize this encryptedData for encoding - */ -SECStatus -NSS_CMSEncryptedData_Encode_AfterData(NSSCMSEncryptedData *encd) -{ - if (encd->contentInfo.ciphcx) { - NSS_CMSCipherContext_Destroy(encd->contentInfo.ciphcx); - encd->contentInfo.ciphcx = NULL; - } - - /* nothing to do after data */ - return SECSuccess; -} - - -/* - * NSS_CMSEncryptedData_Decode_BeforeData - find bulk key & set up decryption - */ -SECStatus -NSS_CMSEncryptedData_Decode_BeforeData(NSSCMSEncryptedData *encd) -{ - PK11SymKey *bulkkey = NULL; - NSSCMSContentInfo *cinfo; - SECAlgorithmID *bulkalg; - SECStatus rv = SECFailure; - - cinfo = &(encd->contentInfo); - - bulkalg = NSS_CMSContentInfo_GetContentEncAlg(cinfo); - - if (encd->cmsg->decrypt_key_cb == NULL) /* no callback? no key../ */ - goto loser; - - bulkkey = (*encd->cmsg->decrypt_key_cb)(encd->cmsg->decrypt_key_cb_arg, bulkalg); - if (bulkkey == NULL) - /* no success finding a bulk key */ - goto loser; - - NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey); - - cinfo->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg); - if (cinfo->ciphcx == NULL) - goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */ - - - /* we are done with (this) bulkkey now. */ - PK11_FreeSymKey(bulkkey); - - rv = SECSuccess; - -loser: - return rv; -} - -/* - * NSS_CMSEncryptedData_Decode_AfterData - finish decrypting this encryptedData's content - */ -SECStatus -NSS_CMSEncryptedData_Decode_AfterData(NSSCMSEncryptedData *encd) -{ - if (encd->contentInfo.ciphcx) { - NSS_CMSCipherContext_Destroy(encd->contentInfo.ciphcx); - encd->contentInfo.ciphcx = NULL; - } - - return SECSuccess; -} - -/* - * NSS_CMSEncryptedData_Decode_AfterEnd - finish decoding this encryptedData - */ -SECStatus -NSS_CMSEncryptedData_Decode_AfterEnd(NSSCMSEncryptedData *encd) -{ - /* apply final touches */ - return SECSuccess; -} diff --git a/security/nss/lib/smime/cmsencode.c b/security/nss/lib/smime/cmsencode.c deleted file mode 100644 index 34e097cf2..000000000 --- a/security/nss/lib/smime/cmsencode.c +++ /dev/null @@ -1,745 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS encoding. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "cert.h" -#include "key.h" -#include "secasn1.h" -#include "secoid.h" -#include "secitem.h" -#include "pk11func.h" -#include "secerr.h" - -struct nss_cms_encoder_output { - NSSCMSContentCallback outputfn; - void *outputarg; - PLArenaPool *destpoolp; - SECItem *dest; -}; - -struct NSSCMSEncoderContextStr { - SEC_ASN1EncoderContext * ecx; /* ASN.1 encoder context */ - PRBool ecxupdated; /* true if data was handed in */ - NSSCMSMessage * cmsg; /* pointer to the root message */ - SECOidTag type; /* type tag of the current content */ - NSSCMSContent content; /* pointer to current content */ - struct nss_cms_encoder_output output; /* output function */ - int error; /* error code */ - NSSCMSEncoderContext * childp7ecx; /* link to child encoder context */ -}; - -static SECStatus nss_cms_before_data(NSSCMSEncoderContext *p7ecx); -static SECStatus nss_cms_after_data(NSSCMSEncoderContext *p7ecx); -static SECStatus nss_cms_encoder_update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len); -static SECStatus nss_cms_encoder_work_data(NSSCMSEncoderContext *p7ecx, SECItem *dest, - const unsigned char *data, unsigned long len, - PRBool final, PRBool innermost); - -extern const SEC_ASN1Template NSSCMSMessageTemplate[]; - -/* - * The little output function that the ASN.1 encoder calls to hand - * us bytes which we in turn hand back to our caller (via the callback - * they gave us). - */ -static void -nss_cms_encoder_out(void *arg, const char *buf, unsigned long len, - int depth, SEC_ASN1EncodingPart data_kind) -{ - struct nss_cms_encoder_output *output = (struct nss_cms_encoder_output *)arg; - unsigned char *dest; - unsigned long offset; - -#ifdef CMSDEBUG - int i; - - fprintf(stderr, "kind = %d, depth = %d, len = %d\n", data_kind, depth, len); - for (i=0; i < len; i++) { - fprintf(stderr, " %02x%s", (unsigned int)buf[i] & 0xff, ((i % 16) == 15) ? "\n" : ""); - } - if ((i % 16) != 0) - fprintf(stderr, "\n"); -#endif - - if (output->outputfn != NULL) - /* call output callback with DER data */ - output->outputfn(output->outputarg, buf, len); - - if (output->dest != NULL) { - /* store DER data in SECItem */ - offset = output->dest->len; - if (offset == 0) { - dest = (unsigned char *)PORT_ArenaAlloc(output->destpoolp, len); - } else { - dest = (unsigned char *)PORT_ArenaGrow(output->destpoolp, - output->dest->data, - output->dest->len, - output->dest->len + len); - } - if (dest == NULL) - /* oops */ - return; - - output->dest->data = dest; - output->dest->len += len; - - /* copy it in */ - PORT_Memcpy(output->dest->data + offset, buf, len); - } -} - -/* - * nss_cms_encoder_notify - ASN.1 encoder callback - * - * this function is called by the ASN.1 encoder before and after the encoding of - * every object. here, it is used to keep track of data structures, set up - * encryption and/or digesting and possibly set up child encoders. - */ -static void -nss_cms_encoder_notify(void *arg, PRBool before, void *dest, int depth) -{ - NSSCMSEncoderContext *p7ecx; - NSSCMSContentInfo *rootcinfo, *cinfo; - PRBool after = !before; - PLArenaPool *poolp; - SECOidTag childtype; - SECItem *item; - - p7ecx = (NSSCMSEncoderContext *)arg; - PORT_Assert(p7ecx != NULL); - - rootcinfo = &(p7ecx->cmsg->contentInfo); - poolp = p7ecx->cmsg->poolp; - -#ifdef CMSDEBUG - fprintf(stderr, "%6.6s, dest = 0x%08x, depth = %d\n", before ? "before" : "after", dest, depth); -#endif - - /* - * Watch for the content field, at which point we want to instruct - * the ASN.1 encoder to start taking bytes from the buffer. - */ - switch (p7ecx->type) { - default: - case SEC_OID_UNKNOWN: - /* we're still in the root message */ - if (after && dest == &(rootcinfo->contentType)) { - /* got the content type OID now - so find out the type tag */ - p7ecx->type = NSS_CMSContentInfo_GetContentTypeTag(rootcinfo); - /* set up a pointer to our current content */ - p7ecx->content = rootcinfo->content; - } - break; - - case SEC_OID_PKCS7_DATA: - if (before && dest == &(rootcinfo->rawContent)) { - /* just set up encoder to grab from user - no encryption or digesting */ - if ((item = rootcinfo->content.data) != NULL) - (void)nss_cms_encoder_work_data(p7ecx, NULL, item->data, item->len, PR_TRUE, PR_TRUE); - else - SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx); - SEC_ASN1EncoderClearNotifyProc(p7ecx->ecx); /* no need to get notified anymore */ - } - break; - - case SEC_OID_PKCS7_SIGNED_DATA: - case SEC_OID_PKCS7_ENVELOPED_DATA: - case SEC_OID_PKCS7_DIGESTED_DATA: - case SEC_OID_PKCS7_ENCRYPTED_DATA: - - /* when we know what the content is, we encode happily until we reach the inner content */ - cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type); - childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo); - - if (after && dest == &(cinfo->contentType)) { - /* we're right before encoding the data (if we have some or not) */ - /* (for encrypted data, we're right before the contentEncAlg which may change */ - /* in nss_cms_before_data because of IV calculation when setting up encryption) */ - if (nss_cms_before_data(p7ecx) != SECSuccess) - p7ecx->error = PORT_GetError(); - } - if (before && dest == &(cinfo->rawContent)) { - if (childtype == SEC_OID_PKCS7_DATA && (item = cinfo->content.data) != NULL) - /* we have data - feed it in */ - (void)nss_cms_encoder_work_data(p7ecx, NULL, item->data, item->len, PR_TRUE, PR_TRUE); - else - /* else try to get it from user */ - SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx); - } - if (after && dest == &(cinfo->rawContent)) { - if (nss_cms_after_data(p7ecx) != SECSuccess) - p7ecx->error = PORT_GetError(); - SEC_ASN1EncoderClearNotifyProc(p7ecx->ecx); /* no need to get notified anymore */ - } - break; - } -} - -/* - * nss_cms_before_data - setup the current encoder to receive data - */ -static SECStatus -nss_cms_before_data(NSSCMSEncoderContext *p7ecx) -{ - SECStatus rv; - SECOidTag childtype; - NSSCMSContentInfo *cinfo; - PLArenaPool *poolp; - NSSCMSEncoderContext *childp7ecx; - const SEC_ASN1Template *template; - - poolp = p7ecx->cmsg->poolp; - - /* call _Encode_BeforeData handlers */ - switch (p7ecx->type) { - case SEC_OID_PKCS7_SIGNED_DATA: - /* we're encoding a signedData, so set up the digests */ - rv = NSS_CMSSignedData_Encode_BeforeData(p7ecx->content.signedData); - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - /* we're encoding a digestedData, so set up the digest */ - rv = NSS_CMSDigestedData_Encode_BeforeData(p7ecx->content.digestedData); - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - rv = NSS_CMSEnvelopedData_Encode_BeforeData(p7ecx->content.envelopedData); - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - rv = NSS_CMSEncryptedData_Encode_BeforeData(p7ecx->content.encryptedData); - break; - default: - rv = SECFailure; - } - if (rv != SECSuccess) - return SECFailure; - - /* ok, now we have a pointer to cinfo */ - /* find out what kind of data is encapsulated */ - - cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type); - childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo); - - switch (childtype) { - case SEC_OID_PKCS7_SIGNED_DATA: - case SEC_OID_PKCS7_ENVELOPED_DATA: - case SEC_OID_PKCS7_ENCRYPTED_DATA: - case SEC_OID_PKCS7_DIGESTED_DATA: -#if 0 - case SEC_OID_PKCS7_DATA: /* XXX here also??? maybe yes! */ -#endif - /* in these cases, we need to set up a child encoder! */ - /* create new encoder context */ - childp7ecx = PORT_ZAlloc(sizeof(NSSCMSEncoderContext)); - if (childp7ecx == NULL) - return SECFailure; - - /* the CHILD encoder needs to hand its encoded data to the CURRENT encoder - * (which will encrypt and/or digest it) - * this needs to route back into our update function - * which finds the lowest encoding context & encrypts and computes digests */ - childp7ecx->type = childtype; - childp7ecx->content = cinfo->content; - /* use the non-recursive update function here, of course */ - childp7ecx->output.outputfn = (NSSCMSContentCallback)nss_cms_encoder_update; - childp7ecx->output.outputarg = p7ecx; - childp7ecx->output.destpoolp = NULL; - childp7ecx->output.dest = NULL; - childp7ecx->cmsg = p7ecx->cmsg; - - template = NSS_CMSUtil_GetTemplateByTypeTag(childtype); - if (template == NULL) - goto loser; /* cannot happen */ - - /* now initialize the data for encoding the first third */ - switch (childp7ecx->type) { - case SEC_OID_PKCS7_SIGNED_DATA: - rv = NSS_CMSSignedData_Encode_BeforeStart(cinfo->content.signedData); - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - rv = NSS_CMSEnvelopedData_Encode_BeforeStart(cinfo->content.envelopedData); - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - rv = NSS_CMSDigestedData_Encode_BeforeStart(cinfo->content.digestedData); - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - rv = NSS_CMSEncryptedData_Encode_BeforeStart(cinfo->content.encryptedData); - break; - case SEC_OID_PKCS7_DATA: - rv = SECSuccess; - break; - default: - PORT_Assert(0); - break; - } - if (rv != SECSuccess) - goto loser; - - /* - * Initialize the BER encoder. - */ - childp7ecx->ecx = SEC_ASN1EncoderStart(cinfo->content.pointer, template, - nss_cms_encoder_out, &(childp7ecx->output)); - if (childp7ecx->ecx == NULL) - goto loser; - - childp7ecx->ecxupdated = PR_FALSE; - - /* - * Indicate that we are streaming. We will be streaming until we - * get past the contents bytes. - */ - SEC_ASN1EncoderSetStreaming(childp7ecx->ecx); - - /* - * The notify function will watch for the contents field. - */ - SEC_ASN1EncoderSetNotifyProc(childp7ecx->ecx, nss_cms_encoder_notify, childp7ecx); - - /* please note that we are NOT calling SEC_ASN1EncoderUpdate here to kick off the */ - /* encoding process - we'll do that from the update function instead */ - /* otherwise we'd be encoding data from a call of the notify function of the */ - /* parent encoder (which would not work) */ - - /* this will kick off the encoding process & encode everything up to the content bytes, - * at which point the notify function sets streaming mode (and possibly creates - * another child encoder). */ - if (SEC_ASN1EncoderUpdate(childp7ecx->ecx, NULL, 0) != SECSuccess) - goto loser; - - p7ecx->childp7ecx = childp7ecx; - break; - - case SEC_OID_PKCS7_DATA: - p7ecx->childp7ecx = NULL; - break; - default: - /* we do not know this type */ - p7ecx->error = SEC_ERROR_BAD_DER; - break; - } - - return SECSuccess; - -loser: - if (childp7ecx) { - if (childp7ecx->ecx) - SEC_ASN1EncoderFinish(childp7ecx->ecx); - PORT_Free(childp7ecx); - } - return SECFailure; -} - -static SECStatus -nss_cms_after_data(NSSCMSEncoderContext *p7ecx) -{ - SECStatus rv = SECFailure; - - switch (p7ecx->type) { - case SEC_OID_PKCS7_SIGNED_DATA: - /* this will finish the digests and sign */ - rv = NSS_CMSSignedData_Encode_AfterData(p7ecx->content.signedData); - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - rv = NSS_CMSEnvelopedData_Encode_AfterData(p7ecx->content.envelopedData); - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - rv = NSS_CMSDigestedData_Encode_AfterData(p7ecx->content.digestedData); - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - rv = NSS_CMSEncryptedData_Encode_AfterData(p7ecx->content.encryptedData); - break; - case SEC_OID_PKCS7_DATA: - /* do nothing */ - break; - default: - rv = SECFailure; - break; - } - return rv; -} - -/* - * nss_cms_encoder_work_data - process incoming data - * - * (from the user or the next encoding layer) - * Here, we need to digest and/or encrypt, then pass it on - */ -static SECStatus -nss_cms_encoder_work_data(NSSCMSEncoderContext *p7ecx, SECItem *dest, - const unsigned char *data, unsigned long len, - PRBool final, PRBool innermost) -{ - unsigned char *buf = NULL; - SECStatus rv; - NSSCMSContentInfo *cinfo; - - rv = SECSuccess; /* may as well be optimistic */ - - /* - * We should really have data to process, or we should be trying - * to finish/flush the last block. (This is an overly paranoid - * check since all callers are in this file and simple inspection - * proves they do it right. But it could find a bug in future - * modifications/development, that is why it is here.) - */ - PORT_Assert ((data != NULL && len) || final); - - /* we got data (either from the caller, or from a lower level encoder) */ - cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type); - - /* Update the running digest. */ - if (len && cinfo->digcx != NULL) - NSS_CMSDigestContext_Update(cinfo->digcx, data, len); - - /* Encrypt this chunk. */ - if (cinfo->ciphcx != NULL) { - unsigned int inlen; /* length of data being encrypted */ - unsigned int outlen; /* length of encrypted data */ - unsigned int buflen; /* length available for encrypted data */ - - inlen = len; - buflen = NSS_CMSCipherContext_EncryptLength(cinfo->ciphcx, inlen, final); - if (buflen == 0) { - /* - * No output is expected, but the input data may be buffered - * so we still have to call Encrypt. - */ - rv = NSS_CMSCipherContext_Encrypt(cinfo->ciphcx, NULL, NULL, 0, - data, inlen, final); - if (final) { - len = 0; - goto done; - } - return rv; - } - - if (dest != NULL) - buf = (unsigned char*)PORT_ArenaAlloc(p7ecx->cmsg->poolp, buflen); - else - buf = (unsigned char*)PORT_Alloc(buflen); - - if (buf == NULL) { - rv = SECFailure; - } else { - rv = NSS_CMSCipherContext_Encrypt(cinfo->ciphcx, buf, &outlen, buflen, - data, inlen, final); - data = buf; - len = outlen; - } - if (rv != SECSuccess) - /* encryption or malloc failed? */ - return rv; - } - - - /* - * at this point (data,len) has everything we'd like to give to the CURRENT encoder - * (which will encode it, then hand it back to the user or the parent encoder) - * We don't encode the data if we're innermost and we're told not to include the data - */ - if (p7ecx->ecx != NULL && len && (!innermost || cinfo->rawContent != NULL)) - rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, (const char *)data, len); - -done: - - if (cinfo->ciphcx != NULL) { - if (dest != NULL) { - dest->data = buf; - dest->len = len; - } else if (buf != NULL) { - PORT_Free (buf); - } - } - return rv; -} - -/* - * nss_cms_encoder_update - deliver encoded data to the next higher level - * - * no recursion here because we REALLY want to end up at the next higher encoder! - */ -static SECStatus -nss_cms_encoder_update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len) -{ - /* XXX Error handling needs help. Return what? Do "Finish" on failure? */ - return nss_cms_encoder_work_data (p7ecx, NULL, (const unsigned char *)data, len, PR_FALSE, PR_FALSE); -} - -/* - * NSS_CMSEncoder_Start - set up encoding of a CMS message - * - * "cmsg" - message to encode - * "outputfn", "outputarg" - callback function for delivery of DER-encoded output - * will not be called if NULL. - * "dest" - if non-NULL, pointer to SECItem that will hold the DER-encoded output - * "destpoolp" - pool to allocate DER-encoded output in - * "pwfn", pwfn_arg" - callback function for getting token password - * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData - * "detached_digestalgs", "detached_digests" - digests from detached content - */ -NSSCMSEncoderContext * -NSS_CMSEncoder_Start(NSSCMSMessage *cmsg, - NSSCMSContentCallback outputfn, void *outputarg, - SECItem *dest, PLArenaPool *destpoolp, - PK11PasswordFunc pwfn, void *pwfn_arg, - NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg, - SECAlgorithmID **detached_digestalgs, SECItem **detached_digests) -{ - NSSCMSEncoderContext *p7ecx; - SECStatus rv; - NSSCMSContentInfo *cinfo; - - NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb, decrypt_key_cb_arg, - detached_digestalgs, detached_digests); - - p7ecx = (NSSCMSEncoderContext *)PORT_ZAlloc(sizeof(NSSCMSEncoderContext)); - if (p7ecx == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return NULL; - } - - p7ecx->cmsg = cmsg; - p7ecx->output.outputfn = outputfn; - p7ecx->output.outputarg = outputarg; - p7ecx->output.dest = dest; - p7ecx->output.destpoolp = destpoolp; - p7ecx->type = SEC_OID_UNKNOWN; - - cinfo = NSS_CMSMessage_GetContentInfo(cmsg); - - switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) { - case SEC_OID_PKCS7_SIGNED_DATA: - rv = NSS_CMSSignedData_Encode_BeforeStart(cinfo->content.signedData); - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - rv = NSS_CMSEnvelopedData_Encode_BeforeStart(cinfo->content.envelopedData); - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - rv = NSS_CMSDigestedData_Encode_BeforeStart(cinfo->content.digestedData); - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - rv = NSS_CMSEncryptedData_Encode_BeforeStart(cinfo->content.encryptedData); - break; - default: - rv = SECFailure; - break; - } - if (rv != SECSuccess) - return NULL; - - /* Initialize the BER encoder. - * Note that this will not encode anything until the first call to SEC_ASN1EncoderUpdate */ - p7ecx->ecx = SEC_ASN1EncoderStart(cmsg, NSSCMSMessageTemplate, - nss_cms_encoder_out, &(p7ecx->output)); - if (p7ecx->ecx == NULL) { - PORT_Free (p7ecx); - return NULL; - } - p7ecx->ecxupdated = PR_FALSE; - - /* - * Indicate that we are streaming. We will be streaming until we - * get past the contents bytes. - */ - SEC_ASN1EncoderSetStreaming(p7ecx->ecx); - - /* - * The notify function will watch for the contents field. - */ - SEC_ASN1EncoderSetNotifyProc(p7ecx->ecx, nss_cms_encoder_notify, p7ecx); - - /* this will kick off the encoding process & encode everything up to the content bytes, - * at which point the notify function sets streaming mode (and possibly creates - * a child encoder). */ - if (SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0) != SECSuccess) { - PORT_Free (p7ecx); - return NULL; - } - - return p7ecx; -} - -/* - * NSS_CMSEncoder_Update - take content data delivery from the user - * - * "p7ecx" - encoder context - * "data" - content data - * "len" - length of content data - * - * need to find the lowest level (and call SEC_ASN1EncoderUpdate on the way down), - * then hand the data to the work_data fn - */ -SECStatus -NSS_CMSEncoder_Update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len) -{ - SECStatus rv; - NSSCMSContentInfo *cinfo; - SECOidTag childtype; - - if (p7ecx->error) - return SECFailure; - - /* hand data to the innermost decoder */ - if (p7ecx->childp7ecx) { - /* recursion here */ - rv = NSS_CMSEncoder_Update(p7ecx->childp7ecx, data, len); - } else { - /* we are at innermost decoder */ - /* find out about our inner content type - must be data */ - cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type); - childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo); - if (childtype != SEC_OID_PKCS7_DATA) - return SECFailure; - /* and we must not have preset data */ - if (cinfo->content.data != NULL) - return SECFailure; - - /* hand it the data so it can encode it (let DER trickle up the chain) */ - rv = nss_cms_encoder_work_data(p7ecx, NULL, (const unsigned char *)data, len, PR_FALSE, PR_TRUE); - } - return rv; -} - -/* - * NSS_CMSEncoder_Cancel - stop all encoding - * - * we need to walk down the chain of encoders and the finish them from the innermost out - */ -SECStatus -NSS_CMSEncoder_Cancel(NSSCMSEncoderContext *p7ecx) -{ - SECStatus rv = SECFailure; - - /* XXX do this right! */ - - /* - * Finish any inner decoders before us so that all the encoded data is flushed - * This basically finishes all the decoders from the innermost to the outermost. - * Finishing an inner decoder may result in data being updated to the outer decoder - * while we are already in NSS_CMSEncoder_Finish, but that's allright. - */ - if (p7ecx->childp7ecx) { - rv = NSS_CMSEncoder_Cancel(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */ - /* remember rv for now */ - } - - /* - * On the way back up, there will be no more data (if we had an - * inner encoder, it is done now!) - * Flush out any remaining data and/or finish digests. - */ - rv = nss_cms_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE, (p7ecx->childp7ecx == NULL)); - if (rv != SECSuccess) - goto loser; - - p7ecx->childp7ecx = NULL; - - /* kick the encoder back into working mode again. - * We turn off streaming stuff (which will cause the encoder to continue - * encoding happily, now that we have all the data (like digests) ready for it). - */ - SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx); - SEC_ASN1EncoderClearStreaming(p7ecx->ecx); - - /* now that TakeFromBuf is off, this will kick this encoder to finish encoding */ - rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0); - -loser: - SEC_ASN1EncoderFinish(p7ecx->ecx); - PORT_Free (p7ecx); - return rv; -} - -/* - * NSS_CMSEncoder_Finish - signal the end of data - * - * we need to walk down the chain of encoders and the finish them from the innermost out - */ -SECStatus -NSS_CMSEncoder_Finish(NSSCMSEncoderContext *p7ecx) -{ - SECStatus rv = SECFailure; - NSSCMSContentInfo *cinfo; - SECOidTag childtype; - - /* - * Finish any inner decoders before us so that all the encoded data is flushed - * This basically finishes all the decoders from the innermost to the outermost. - * Finishing an inner decoder may result in data being updated to the outer decoder - * while we are already in NSS_CMSEncoder_Finish, but that's allright. - */ - if (p7ecx->childp7ecx) { - rv = NSS_CMSEncoder_Finish(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */ - if (rv != SECSuccess) - goto loser; - } - - /* - * On the way back up, there will be no more data (if we had an - * inner encoder, it is done now!) - * Flush out any remaining data and/or finish digests. - */ - rv = nss_cms_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE, (p7ecx->childp7ecx == NULL)); - if (rv != SECSuccess) - goto loser; - - p7ecx->childp7ecx = NULL; - - /* find out about our inner content type - must be data */ - cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type); - childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo); - if (childtype == SEC_OID_PKCS7_DATA && cinfo->content.data == NULL) { - SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx); - /* now that TakeFromBuf is off, this will kick this encoder to finish encoding */ - rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0); - } - - SEC_ASN1EncoderClearStreaming(p7ecx->ecx); - - if (p7ecx->error) - rv = SECFailure; - -loser: - SEC_ASN1EncoderFinish(p7ecx->ecx); - PORT_Free (p7ecx); - return rv; -} diff --git a/security/nss/lib/smime/cmsenvdata.c b/security/nss/lib/smime/cmsenvdata.c deleted file mode 100644 index c575a995e..000000000 --- a/security/nss/lib/smime/cmsenvdata.c +++ /dev/null @@ -1,421 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS envelopedData methods. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "cert.h" -#include "key.h" -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "pk11func.h" -#include "secerr.h" -#include "secpkcs5.h" - -/* - * NSS_CMSEnvelopedData_Create - create an enveloped data message - */ -NSSCMSEnvelopedData * -NSS_CMSEnvelopedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize) -{ - void *mark; - NSSCMSEnvelopedData *envd; - PLArenaPool *poolp; - SECStatus rv; - - poolp = cmsg->poolp; - - mark = PORT_ArenaMark(poolp); - - envd = (NSSCMSEnvelopedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSEnvelopedData)); - if (envd == NULL) - goto loser; - - envd->cmsg = cmsg; - - /* version is set in NSS_CMSEnvelopedData_Encode_BeforeStart() */ - - rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(envd->contentInfo), algorithm, NULL, keysize); - if (rv != SECSuccess) - goto loser; - - PORT_ArenaUnmark(poolp, mark); - return envd; - -loser: - PORT_ArenaRelease(poolp, mark); - return NULL; -} - -/* - * NSS_CMSEnvelopedData_Destroy - destroy an enveloped data message - */ -void -NSS_CMSEnvelopedData_Destroy(NSSCMSEnvelopedData *edp) -{ - NSSCMSRecipientInfo **recipientinfos; - NSSCMSRecipientInfo *ri; - - if (edp == NULL) - return; - - recipientinfos = edp->recipientInfos; - if (recipientinfos == NULL) - return; - - while ((ri = *recipientinfos++) != NULL) - NSS_CMSRecipientInfo_Destroy(ri); - - NSS_CMSContentInfo_Destroy(&(edp->contentInfo)); - -} - -/* - * NSS_CMSEnvelopedData_GetContentInfo - return pointer to this envelopedData's contentinfo - */ -NSSCMSContentInfo * -NSS_CMSEnvelopedData_GetContentInfo(NSSCMSEnvelopedData *envd) -{ - return &(envd->contentInfo); -} - -/* - * NSS_CMSEnvelopedData_AddRecipient - add a recipientinfo to the enveloped data msg - * - * rip must be created on the same pool as edp - this is not enforced, though. - */ -SECStatus -NSS_CMSEnvelopedData_AddRecipient(NSSCMSEnvelopedData *edp, NSSCMSRecipientInfo *rip) -{ - void *mark; - SECStatus rv; - - /* XXX compare pools, if not same, copy rip into edp's pool */ - - PR_ASSERT(edp != NULL); - PR_ASSERT(rip != NULL); - - mark = PORT_ArenaMark(edp->cmsg->poolp); - - rv = NSS_CMSArray_Add(edp->cmsg->poolp, (void ***)&(edp->recipientInfos), (void *)rip); - if (rv != SECSuccess) { - PORT_ArenaRelease(edp->cmsg->poolp, mark); - return SECFailure; - } - - PORT_ArenaUnmark (edp->cmsg->poolp, mark); - return SECSuccess; -} - -/* - * NSS_CMSEnvelopedData_Encode_BeforeStart - prepare this envelopedData for encoding - * - * at this point, we need - * - recipientinfos set up with recipient's certificates - * - a content encryption algorithm (if none, 3DES will be used) - * - * this function will generate a random content encryption key (aka bulk key), - * initialize the recipientinfos with certificate identification and wrap the bulk key - * using the proper algorithm for every certificiate. - * it will finally set the bulk algorithm and key so that the encode step can find it. - */ -SECStatus -NSS_CMSEnvelopedData_Encode_BeforeStart(NSSCMSEnvelopedData *envd) -{ - int version; - NSSCMSRecipientInfo **recipientinfos; - NSSCMSContentInfo *cinfo; - PK11SymKey *bulkkey = NULL; - SECOidTag bulkalgtag; - CK_MECHANISM_TYPE type; - PK11SlotInfo *slot; - SECStatus rv; - SECItem *dummy; - PLArenaPool *poolp; - extern const SEC_ASN1Template NSSCMSRecipientInfoTemplate[]; - void *mark = NULL; - int i; - - poolp = envd->cmsg->poolp; - cinfo = &(envd->contentInfo); - - recipientinfos = envd->recipientInfos; - if (recipientinfos == NULL) { - PORT_SetError(SEC_ERROR_BAD_DATA); -#if 0 - PORT_SetErrorString("Cannot find recipientinfos to encode."); -#endif - goto loser; - } - - version = NSS_CMS_ENVELOPED_DATA_VERSION_REG; - if (envd->originatorInfo != NULL || envd->unprotectedAttr != NULL) { - version = NSS_CMS_ENVELOPED_DATA_VERSION_ADV; - } else { - for (i = 0; recipientinfos[i] != NULL; i++) { - if (NSS_CMSRecipientInfo_GetVersion(recipientinfos[i]) != 0) { - version = NSS_CMS_ENVELOPED_DATA_VERSION_ADV; - break; - } - } - } - dummy = SEC_ASN1EncodeInteger(poolp, &(envd->version), version); - if (dummy == NULL) - goto loser; - - /* now we need to have a proper content encryption algorithm - * on the SMIME level, we would figure one out by looking at SMIME capabilities - * we cannot do that on our level, so if none is set already, we'll just go - * with one of the mandatory algorithms (3DES) */ - if ((bulkalgtag = NSS_CMSContentInfo_GetContentEncAlgTag(cinfo)) == SEC_OID_UNKNOWN) { - rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, cinfo, SEC_OID_DES_EDE3_CBC, NULL, 168); - if (rv != SECSuccess) - goto loser; - bulkalgtag = SEC_OID_DES_EDE3_CBC; - } - - /* generate a random bulk key suitable for content encryption alg */ - type = PK11_AlgtagToMechanism(bulkalgtag); - slot = PK11_GetBestSlot(type, envd->cmsg->pwfn_arg); - if (slot == NULL) - goto loser; /* error has been set by PK11_GetBestSlot */ - - /* this is expensive... */ - bulkkey = PK11_KeyGen(slot, type, NULL, NSS_CMSContentInfo_GetBulkKeySize(cinfo) / 8, envd->cmsg->pwfn_arg); - PK11_FreeSlot(slot); - if (bulkkey == NULL) - goto loser; /* error has been set by PK11_KeyGen */ - - mark = PORT_ArenaMark(poolp); - - /* Encrypt the bulk key with the public key of each recipient. */ - for (i = 0; recipientinfos[i] != NULL; i++) { - rv = NSS_CMSRecipientInfo_WrapBulkKey(recipientinfos[i], bulkkey, bulkalgtag); - if (rv != SECSuccess) - goto loser; /* error has been set by NSS_CMSRecipientInfo_EncryptBulkKey */ - /* could be: alg not supported etc. */ - } - - /* the recipientinfos are all finished. now sort them by DER for SET OF encoding */ - rv = NSS_CMSArray_SortByDER((void **)envd->recipientInfos, NSSCMSRecipientInfoTemplate, NULL); - if (rv != SECSuccess) - goto loser; /* error has been set by NSS_CMSArray_SortByDER */ - - /* store the bulk key in the contentInfo so that the encoder can find it */ - NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey); - - PORT_ArenaUnmark(poolp, mark); - - PK11_FreeSymKey(bulkkey); - - return SECSuccess; - -loser: - if (mark != NULL) - PORT_ArenaRelease (poolp, mark); - if (bulkkey) - PK11_FreeSymKey(bulkkey); - - return SECFailure; -} - -/* - * NSS_CMSEnvelopedData_Encode_BeforeData - set up encryption - * - * it is essential that this is called before the contentEncAlg is encoded, because - * setting up the encryption may generate IVs and thus change it! - */ -SECStatus -NSS_CMSEnvelopedData_Encode_BeforeData(NSSCMSEnvelopedData *envd) -{ - NSSCMSContentInfo *cinfo; - PK11SymKey *bulkkey; - SECAlgorithmID *algid; - - cinfo = &(envd->contentInfo); - - /* find bulkkey and algorithm - must have been set by NSS_CMSEnvelopedData_Encode_BeforeStart */ - bulkkey = NSS_CMSContentInfo_GetBulkKey(cinfo); - if (bulkkey == NULL) - return SECFailure; - algid = NSS_CMSContentInfo_GetContentEncAlg(cinfo); - if (algid == NULL) - return SECFailure; - - /* this may modify algid (with IVs generated in a token). - * it is essential that algid is a pointer to the contentEncAlg data, not a - * pointer to a copy! */ - cinfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(envd->cmsg->poolp, bulkkey, algid); - PK11_FreeSymKey(bulkkey); - if (cinfo->ciphcx == NULL) - return SECFailure; - - return SECSuccess; -} - -/* - * NSS_CMSEnvelopedData_Encode_AfterData - finalize this envelopedData for encoding - */ -SECStatus -NSS_CMSEnvelopedData_Encode_AfterData(NSSCMSEnvelopedData *envd) -{ - if (envd->contentInfo.ciphcx) { - NSS_CMSCipherContext_Destroy(envd->contentInfo.ciphcx); - envd->contentInfo.ciphcx = NULL; - } - - /* nothing else to do after data */ - return SECSuccess; -} - -/* - * NSS_CMSEnvelopedData_Decode_BeforeData - find our recipientinfo, - * derive bulk key & set up our contentinfo - */ -SECStatus -NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd) -{ - NSSCMSRecipientInfo *ri; - PK11SymKey *bulkkey = NULL; - SECOidTag bulkalgtag; - SECAlgorithmID *bulkalg; - SECStatus rv = SECFailure; - NSSCMSContentInfo *cinfo; - NSSCMSRecipient **recipient_list = NULL; - NSSCMSRecipient *recipient; - int rlIndex; - - if (NSS_CMSArray_Count((void **)envd->recipientInfos) == 0) { - PORT_SetError(SEC_ERROR_BAD_DATA); -#if 0 - PORT_SetErrorString("No recipient data in envelope."); -#endif - goto loser; - } - - /* look if one of OUR cert's issuerSN is on the list of recipients, and if so, */ - /* get the cert and private key for it right away */ - recipient_list = nss_cms_recipient_list_create(envd->recipientInfos); - if (recipient_list == NULL) - goto loser; - - /* what about multiple recipientInfos that match? - * especially if, for some reason, we could not produce a bulk key with the first match?! - * we could loop & feed partial recipient_list to PK11_FindCertAndKeyByRecipientList... - * maybe later... */ - rlIndex = PK11_FindCertAndKeyByRecipientListNew(recipient_list, envd->cmsg->pwfn_arg); - - /* if that fails, then we're not an intended recipient and cannot decrypt */ - if (rlIndex < 0) { - PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT); -#if 0 - PORT_SetErrorString("Cannot decrypt data because proper key cannot be found."); -#endif - goto loser; - } - - recipient = recipient_list[rlIndex]; - if (!recipient->cert || !recipient->privkey) { - /* XXX should set an error code ?!? */ - goto loser; - } - /* get a pointer to "our" recipientinfo */ - ri = envd->recipientInfos[recipient->riIndex]; - - cinfo = &(envd->contentInfo); - bulkalgtag = NSS_CMSContentInfo_GetContentEncAlgTag(cinfo); - if (bulkalgtag == SEC_OID_UNKNOWN) { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - } else - bulkkey = - NSS_CMSRecipientInfo_UnwrapBulkKey(ri,recipient->subIndex, - recipient->cert, - recipient->privkey, - bulkalgtag); - if (bulkkey == NULL) { - /* no success finding a bulk key */ - goto loser; - } - - NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey); - - bulkalg = NSS_CMSContentInfo_GetContentEncAlg(cinfo); - - cinfo->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg); - if (cinfo->ciphcx == NULL) - goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */ - - - rv = SECSuccess; - -loser: - if (bulkkey) - PK11_FreeSymKey(bulkkey); - if (recipient_list != NULL) - nss_cms_recipient_list_destroy(recipient_list); - return rv; -} - -/* - * NSS_CMSEnvelopedData_Decode_AfterData - finish decrypting this envelopedData's content - */ -SECStatus -NSS_CMSEnvelopedData_Decode_AfterData(NSSCMSEnvelopedData *envd) -{ - if (envd && envd->contentInfo.ciphcx) { - NSS_CMSCipherContext_Destroy(envd->contentInfo.ciphcx); - envd->contentInfo.ciphcx = NULL; - } - - return SECSuccess; -} - -/* - * NSS_CMSEnvelopedData_Decode_AfterEnd - finish decoding this envelopedData - */ -SECStatus -NSS_CMSEnvelopedData_Decode_AfterEnd(NSSCMSEnvelopedData *envd) -{ - /* apply final touches */ - return SECSuccess; -} - diff --git a/security/nss/lib/smime/cmslocal.h b/security/nss/lib/smime/cmslocal.h deleted file mode 100644 index 666eeb033..000000000 --- a/security/nss/lib/smime/cmslocal.h +++ /dev/null @@ -1,346 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * Support routines for CMS implementation, none of which are exported. - * - * Do not export this file! If something in here is really needed outside - * of smime code, first try to add a CMS interface which will do it for - * you. If that has a problem, then just move out what you need, changing - * its name as appropriate! - * - * $Id$ - */ - -#ifndef _CMSLOCAL_H_ -#define _CMSLOCAL_H_ - -#include "cms.h" -#include "cmsreclist.h" -#include "secasn1t.h" - -extern const SEC_ASN1Template NSSCMSContentInfoTemplate[]; - -/************************************************************************/ -SEC_BEGIN_PROTOS - -/*********************************************************************** - * cmscipher.c - en/decryption routines - ***********************************************************************/ - -/* - * NSS_CMSCipherContext_StartDecrypt - create a cipher context to do decryption - * based on the given bulk * encryption key and algorithm identifier (which may include an iv). - */ -extern NSSCMSCipherContext * -NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid); - -/* - * NSS_CMSCipherContext_StartEncrypt - create a cipher object to do encryption, - * based on the given bulk encryption key and algorithm tag. Fill in the algorithm - * identifier (which may include an iv) appropriately. - */ -extern NSSCMSCipherContext * -NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgorithmID *algid); - -extern void -NSS_CMSCipherContext_Destroy(NSSCMSCipherContext *cc); - -/* - * NSS_CMSCipherContext_DecryptLength - find the output length of the next call to decrypt. - * - * cc - the cipher context - * input_len - number of bytes used as input - * final - true if this is the final chunk of data - * - * Result can be used to perform memory allocations. Note that the amount - * is exactly accurate only when not doing a block cipher or when final - * is false, otherwise it is an upper bound on the amount because until - * we see the data we do not know how many padding bytes there are - * (always between 1 and bsize). - */ -extern unsigned int -NSS_CMSCipherContext_DecryptLength(NSSCMSCipherContext *cc, unsigned int input_len, PRBool final); - -/* - * NSS_CMSCipherContext_EncryptLength - find the output length of the next call to encrypt. - * - * cc - the cipher context - * input_len - number of bytes used as input - * final - true if this is the final chunk of data - * - * Result can be used to perform memory allocations. - */ -extern unsigned int -NSS_CMSCipherContext_EncryptLength(NSSCMSCipherContext *cc, unsigned int input_len, PRBool final); - -/* - * NSS_CMSCipherContext_Decrypt - do the decryption - * - * cc - the cipher context - * output - buffer for decrypted result bytes - * output_len_p - number of bytes in output - * max_output_len - upper bound on bytes to put into output - * input - pointer to input bytes - * input_len - number of input bytes - * final - true if this is the final chunk of data - * - * Decrypts a given length of input buffer (starting at "input" and - * containing "input_len" bytes), placing the decrypted bytes in - * "output" and storing the output length in "*output_len_p". - * "cc" is the return value from NSS_CMSCipher_StartDecrypt. - * When "final" is true, this is the last of the data to be decrypted. - */ -extern SECStatus -NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output, - unsigned int *output_len_p, unsigned int max_output_len, - const unsigned char *input, unsigned int input_len, - PRBool final); - -/* - * NSS_CMSCipherContext_Encrypt - do the encryption - * - * cc - the cipher context - * output - buffer for decrypted result bytes - * output_len_p - number of bytes in output - * max_output_len - upper bound on bytes to put into output - * input - pointer to input bytes - * input_len - number of input bytes - * final - true if this is the final chunk of data - * - * Encrypts a given length of input buffer (starting at "input" and - * containing "input_len" bytes), placing the encrypted bytes in - * "output" and storing the output length in "*output_len_p". - * "cc" is the return value from NSS_CMSCipher_StartEncrypt. - * When "final" is true, this is the last of the data to be encrypted. - */ -extern SECStatus -NSS_CMSCipherContext_Encrypt(NSSCMSCipherContext *cc, unsigned char *output, - unsigned int *output_len_p, unsigned int max_output_len, - const unsigned char *input, unsigned int input_len, - PRBool final); - -/************************************************************************ - * cmspubkey.c - public key operations - ************************************************************************/ - -/* - * NSS_CMSUtil_EncryptSymKey_RSA - wrap a symmetric key with RSA - * - * this function takes a symmetric key and encrypts it using an RSA public key - * according to PKCS#1 and RFC2633 (S/MIME) - */ -extern SECStatus -NSS_CMSUtil_EncryptSymKey_RSA(PLArenaPool *poolp, CERTCertificate *cert, - PK11SymKey *key, - SECItem *encKey); - -extern SECStatus -NSS_CMSUtil_EncryptSymKey_RSAPubKey(PLArenaPool *poolp, - SECKEYPublicKey *publickey, - PK11SymKey *bulkkey, SECItem *encKey); - -/* - * NSS_CMSUtil_DecryptSymKey_RSA - unwrap a RSA-wrapped symmetric key - * - * this function takes an RSA-wrapped symmetric key and unwraps it, returning a symmetric - * key handle. Please note that the actual unwrapped key data may not be allowed to leave - * a hardware token... - */ -extern PK11SymKey * -NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOidTag bulkalgtag); - -extern SECStatus -NSS_CMSUtil_EncryptSymKey_MISSI(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key, - SECOidTag symalgtag, SECItem *encKey, SECItem **pparams, void *pwfn_arg); - -extern PK11SymKey * -NSS_CMSUtil_DecryptSymKey_MISSI(SECKEYPrivateKey *privkey, SECItem *encKey, - SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg); - -extern SECStatus -NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key, - SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg, - SECItem *originatorPubKey); - -extern PK11SymKey * -NSS_CMSUtil_DecryptSymKey_ESDH(SECKEYPrivateKey *privkey, SECItem *encKey, - SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg); - -/************************************************************************ - * cmsreclist.c - recipient list stuff - ************************************************************************/ -extern NSSCMSRecipient **nss_cms_recipient_list_create(NSSCMSRecipientInfo **recipientinfos); -extern void nss_cms_recipient_list_destroy(NSSCMSRecipient **recipient_list); -extern NSSCMSRecipientEncryptedKey *NSS_CMSRecipientEncryptedKey_Create(PLArenaPool *poolp); - -/************************************************************************ - * cmsarray.c - misc array functions - ************************************************************************/ -/* - * NSS_CMSArray_Alloc - allocate an array in an arena - */ -extern void ** -NSS_CMSArray_Alloc(PRArenaPool *poolp, int n); - -/* - * NSS_CMSArray_Add - add an element to the end of an array - */ -extern SECStatus -NSS_CMSArray_Add(PRArenaPool *poolp, void ***array, void *obj); - -/* - * NSS_CMSArray_IsEmpty - check if array is empty - */ -extern PRBool -NSS_CMSArray_IsEmpty(void **array); - -/* - * NSS_CMSArray_Count - count number of elements in array - */ -extern int -NSS_CMSArray_Count(void **array); - -/* - * NSS_CMSArray_Sort - sort an array ascending, in place - * - * If "secondary" is not NULL, the same reordering gets applied to it. - * If "tertiary" is not NULL, the same reordering gets applied to it. - * "compare" is a function that returns - * < 0 when the first element is less than the second - * = 0 when the first element is equal to the second - * > 0 when the first element is greater than the second - */ -extern void -NSS_CMSArray_Sort(void **primary, int (*compare)(void *,void *), void **secondary, void **tertiary); - -/************************************************************************ - * cmsattr.c - misc attribute functions - ************************************************************************/ -/* - * NSS_CMSAttribute_Create - create an attribute - * - * if value is NULL, the attribute won't have a value. It can be added later - * with NSS_CMSAttribute_AddValue. - */ -extern NSSCMSAttribute * -NSS_CMSAttribute_Create(PRArenaPool *poolp, SECOidTag oidtag, SECItem *value, PRBool encoded); - -/* - * NSS_CMSAttribute_AddValue - add another value to an attribute - */ -extern SECStatus -NSS_CMSAttribute_AddValue(PLArenaPool *poolp, NSSCMSAttribute *attr, SECItem *value); - -/* - * NSS_CMSAttribute_GetType - return the OID tag - */ -extern SECOidTag -NSS_CMSAttribute_GetType(NSSCMSAttribute *attr); - -/* - * NSS_CMSAttribute_GetValue - return the first attribute value - * - * We do some sanity checking first: - * - Multiple values are *not* expected. - * - Empty values are *not* expected. - */ -extern SECItem * -NSS_CMSAttribute_GetValue(NSSCMSAttribute *attr); - -/* - * NSS_CMSAttribute_CompareValue - compare the attribute's first value against data - */ -extern PRBool -NSS_CMSAttribute_CompareValue(NSSCMSAttribute *attr, SECItem *av); - -/* - * NSS_CMSAttributeArray_Encode - encode an Attribute array as SET OF Attributes - * - * If you are wondering why this routine does not reorder the attributes - * first, and might be tempted to make it do so, see the comment by the - * call to ReorderAttributes in cmsencode.c. (Or, see who else calls this - * and think long and hard about the implications of making it always - * do the reordering.) - */ -extern SECItem * -NSS_CMSAttributeArray_Encode(PRArenaPool *poolp, NSSCMSAttribute ***attrs, SECItem *dest); - -/* - * NSS_CMSAttributeArray_Reorder - sort attribute array by attribute's DER encoding - * - * make sure that the order of the attributes guarantees valid DER (which must be - * in lexigraphically ascending order for a SET OF); if reordering is necessary it - * will be done in place (in attrs). - */ -extern SECStatus -NSS_CMSAttributeArray_Reorder(NSSCMSAttribute **attrs); - -/* - * NSS_CMSAttributeArray_FindAttrByOidTag - look through a set of attributes and - * find one that matches the specified object ID. - * - * If "only" is true, then make sure that there is not more than one attribute - * of the same type. Otherwise, just return the first one found. (XXX Does - * anybody really want that first-found behavior? It was like that when I found it...) - */ -extern NSSCMSAttribute * -NSS_CMSAttributeArray_FindAttrByOidTag(NSSCMSAttribute **attrs, SECOidTag oidtag, PRBool only); - -/* - * NSS_CMSAttributeArray_AddAttr - add an attribute to an - * array of attributes. - */ -extern SECStatus -NSS_CMSAttributeArray_AddAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, NSSCMSAttribute *attr); - -/* - * NSS_CMSAttributeArray_SetAttr - set an attribute's value in a set of attributes - */ -extern SECStatus -NSS_CMSAttributeArray_SetAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, SECOidTag type, SECItem *value, PRBool encoded); - -/* - * NSS_CMSSignedData_AddTempCertificate - add temporary certificate references. - * They may be needed for signature verification on the data, for example. - */ -extern SECStatus -NSS_CMSSignedData_AddTempCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert); - -/************************************************************************/ -SEC_END_PROTOS - -#endif /* _CMSLOCAL_H_ */ diff --git a/security/nss/lib/smime/cmsmessage.c b/security/nss/lib/smime/cmsmessage.c deleted file mode 100644 index 1b3d69c74..000000000 --- a/security/nss/lib/smime/cmsmessage.c +++ /dev/null @@ -1,321 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS message methods. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "cert.h" -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "pk11func.h" -#include "secerr.h" - -/* - * NSS_CMSMessage_Create - create a CMS message object - * - * "poolp" - arena to allocate memory from, or NULL if new arena should be created - */ -NSSCMSMessage * -NSS_CMSMessage_Create(PLArenaPool *poolp) -{ - void *mark = NULL; - NSSCMSMessage *cmsg; - PRBool poolp_is_ours = PR_FALSE; - - if (poolp == NULL) { - poolp = PORT_NewArena (1024); /* XXX what is right value? */ - if (poolp == NULL) - return NULL; - poolp_is_ours = PR_TRUE; - } - - if (!poolp_is_ours) - mark = PORT_ArenaMark(poolp); - - cmsg = (NSSCMSMessage *)PORT_ArenaZAlloc (poolp, sizeof(NSSCMSMessage)); - if (cmsg == NULL) { - if (!poolp_is_ours) { - if (mark) { - PORT_ArenaRelease(poolp, mark); - } - } else - PORT_FreeArena(poolp, PR_FALSE); - return NULL; - } - - cmsg->poolp = poolp; - cmsg->poolp_is_ours = poolp_is_ours; - cmsg->refCount = 1; - - if (mark) - PORT_ArenaUnmark(poolp, mark); - - return cmsg; -} - -/* - * NSS_CMSMessage_SetEncodingParams - set up a CMS message object for encoding or decoding - * - * "cmsg" - message object - * "pwfn", pwfn_arg" - callback function for getting token password - * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData - * "detached_digestalgs", "detached_digests" - digests from detached content - */ -void -NSS_CMSMessage_SetEncodingParams(NSSCMSMessage *cmsg, - PK11PasswordFunc pwfn, void *pwfn_arg, - NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg, - SECAlgorithmID **detached_digestalgs, SECItem **detached_digests) -{ - if (pwfn) - PK11_SetPasswordFunc(pwfn); - cmsg->pwfn_arg = pwfn_arg; - cmsg->decrypt_key_cb = decrypt_key_cb; - cmsg->decrypt_key_cb_arg = decrypt_key_cb_arg; - cmsg->detached_digestalgs = detached_digestalgs; - cmsg->detached_digests = detached_digests; -} - -/* - * NSS_CMSMessage_Destroy - destroy a CMS message and all of its sub-pieces. - */ -void -NSS_CMSMessage_Destroy(NSSCMSMessage *cmsg) -{ - PORT_Assert (cmsg->refCount > 0); - if (cmsg->refCount <= 0) /* oops */ - return; - - cmsg->refCount--; /* thread safety? */ - if (cmsg->refCount > 0) - return; - - NSS_CMSContentInfo_Destroy(&(cmsg->contentInfo)); - - /* if poolp is not NULL, cmsg is the owner of its arena */ - if (cmsg->poolp_is_ours) - PORT_FreeArena (cmsg->poolp, PR_FALSE); /* XXX clear it? */ -} - -/* - * NSS_CMSMessage_Copy - return a copy of the given message. - * - * The copy may be virtual or may be real -- either way, the result needs - * to be passed to NSS_CMSMessage_Destroy later (as does the original). - */ -NSSCMSMessage * -NSS_CMSMessage_Copy(NSSCMSMessage *cmsg) -{ - if (cmsg == NULL) - return NULL; - - PORT_Assert (cmsg->refCount > 0); - - cmsg->refCount++; /* XXX chrisk thread safety? */ - return cmsg; -} - -/* - * NSS_CMSMessage_GetArena - return a pointer to the message's arena pool - */ -PLArenaPool * -NSS_CMSMessage_GetArena(NSSCMSMessage *cmsg) -{ - return cmsg->poolp; -} - -/* - * NSS_CMSMessage_GetContentInfo - return a pointer to the top level contentInfo - */ -NSSCMSContentInfo * -NSS_CMSMessage_GetContentInfo(NSSCMSMessage *cmsg) -{ - return &(cmsg->contentInfo); -} - -/* - * Return a pointer to the actual content. - * In the case of those types which are encrypted, this returns the *plain* content. - * In case of nested contentInfos, this descends and retrieves the innermost content. - */ -SECItem * -NSS_CMSMessage_GetContent(NSSCMSMessage *cmsg) -{ - /* this is a shortcut */ - NSSCMSContentInfo * cinfo = NSS_CMSMessage_GetContentInfo(cmsg); - SECItem * pItem = NSS_CMSContentInfo_GetInnerContent(cinfo); - return pItem; -} - -/* - * NSS_CMSMessage_ContentLevelCount - count number of levels of CMS content objects in this message - * - * CMS data content objects do not count. - */ -int -NSS_CMSMessage_ContentLevelCount(NSSCMSMessage *cmsg) -{ - int count = 0; - NSSCMSContentInfo *cinfo; - - /* walk down the chain of contentinfos */ - for (cinfo = &(cmsg->contentInfo); cinfo != NULL; ) { - count++; - cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo); - } - return count; -} - -/* - * NSS_CMSMessage_ContentLevel - find content level #n - * - * CMS data content objects do not count. - */ -NSSCMSContentInfo * -NSS_CMSMessage_ContentLevel(NSSCMSMessage *cmsg, int n) -{ - int count = 0; - NSSCMSContentInfo *cinfo; - - /* walk down the chain of contentinfos */ - for (cinfo = &(cmsg->contentInfo); cinfo != NULL && count < n; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) { - count++; - } - - return cinfo; -} - -/* - * NSS_CMSMessage_ContainsCertsOrCrls - see if message contains certs along the way - */ -PRBool -NSS_CMSMessage_ContainsCertsOrCrls(NSSCMSMessage *cmsg) -{ - NSSCMSContentInfo *cinfo; - - /* descend into CMS message */ - for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) { - if (NSS_CMSContentInfo_GetContentTypeTag(cinfo) != SEC_OID_PKCS7_SIGNED_DATA) - continue; /* next level */ - - if (NSS_CMSSignedData_ContainsCertsOrCrls(cinfo->content.signedData)) - return PR_TRUE; - } - return PR_FALSE; -} - -/* - * NSS_CMSMessage_IsEncrypted - see if message contains a encrypted submessage - */ -PRBool -NSS_CMSMessage_IsEncrypted(NSSCMSMessage *cmsg) -{ - NSSCMSContentInfo *cinfo; - - /* walk down the chain of contentinfos */ - for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) - { - switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) { - case SEC_OID_PKCS7_ENVELOPED_DATA: - case SEC_OID_PKCS7_ENCRYPTED_DATA: - return PR_TRUE; - default: - break; - } - } - return PR_FALSE; -} - -/* - * NSS_CMSMessage_IsSigned - see if message contains a signed submessage - * - * If the CMS message has a SignedData with a signature (not just a SignedData) - * return true; false otherwise. This can/should be called before calling - * VerifySignature, which will always indicate failure if no signature is - * present, but that does not mean there even was a signature! - * Note that the content itself can be empty (detached content was sent - * another way); it is the presence of the signature that matters. - */ -PRBool -NSS_CMSMessage_IsSigned(NSSCMSMessage *cmsg) -{ - NSSCMSContentInfo *cinfo; - - /* walk down the chain of contentinfos */ - for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) - { - switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) { - case SEC_OID_PKCS7_SIGNED_DATA: - if (!NSS_CMSArray_IsEmpty((void **)cinfo->content.signedData->signerInfos)) - return PR_TRUE; - break; - default: - break; - } - } - return PR_FALSE; -} - -/* - * NSS_CMSMessage_IsContentEmpty - see if content is empty - * - * returns PR_TRUE is innermost content length is < minLen - * XXX need the encrypted content length (why?) - */ -PRBool -NSS_CMSMessage_IsContentEmpty(NSSCMSMessage *cmsg, unsigned int minLen) -{ - SECItem *item = NULL; - - if (cmsg == NULL) - return PR_TRUE; - - item = NSS_CMSContentInfo_GetContent(NSS_CMSMessage_GetContentInfo(cmsg)); - - if (!item) { - return PR_TRUE; - } else if(item->len <= minLen) { - return PR_TRUE; - } - - return PR_FALSE; -} diff --git a/security/nss/lib/smime/cmspubkey.c b/security/nss/lib/smime/cmspubkey.c deleted file mode 100644 index 144dd789d..000000000 --- a/security/nss/lib/smime/cmspubkey.c +++ /dev/null @@ -1,565 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS public key crypto - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "cert.h" -#include "key.h" -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "pk11func.h" -#include "secerr.h" - -/* ====== RSA ======================================================================= */ - -/* - * NSS_CMSUtil_EncryptSymKey_RSA - wrap a symmetric key with RSA - * - * this function takes a symmetric key and encrypts it using an RSA public key - * according to PKCS#1 and RFC2633 (S/MIME) - */ -SECStatus -NSS_CMSUtil_EncryptSymKey_RSA(PLArenaPool *poolp, CERTCertificate *cert, - PK11SymKey *bulkkey, - SECItem *encKey) -{ - SECStatus rv; - SECKEYPublicKey *publickey; - - publickey = CERT_ExtractPublicKey(cert); - if (publickey == NULL) - return SECFailure; - - rv = NSS_CMSUtil_EncryptSymKey_RSAPubKey(poolp, publickey, bulkkey, encKey); - SECKEY_DestroyPublicKey(publickey); - return rv; -} - -SECStatus -NSS_CMSUtil_EncryptSymKey_RSAPubKey(PLArenaPool *poolp, - SECKEYPublicKey *publickey, - PK11SymKey *bulkkey, SECItem *encKey) -{ - SECStatus rv; - int data_len; - KeyType keyType; - void *mark = NULL; - - - mark = PORT_ArenaMark(poolp); - if (!mark) - goto loser; - - /* sanity check */ - keyType = SECKEY_GetPublicKeyType(publickey); - PORT_Assert(keyType == rsaKey); - if (keyType != rsaKey) { - goto loser; - } - /* allocate memory for the encrypted key */ - data_len = SECKEY_PublicKeyStrength(publickey); /* block size (assumed to be > keylen) */ - encKey->data = (unsigned char*)PORT_ArenaAlloc(poolp, data_len); - encKey->len = data_len; - if (encKey->data == NULL) - goto loser; - - /* encrypt the key now */ - rv = PK11_PubWrapSymKey(PK11_AlgtagToMechanism(SEC_OID_PKCS1_RSA_ENCRYPTION), - publickey, bulkkey, encKey); - - if (rv != SECSuccess) - goto loser; - - PORT_ArenaUnmark(poolp, mark); - return SECSuccess; - -loser: - if (mark) { - PORT_ArenaRelease(poolp, mark); - } - return SECFailure; -} - -/* - * NSS_CMSUtil_DecryptSymKey_RSA - unwrap a RSA-wrapped symmetric key - * - * this function takes an RSA-wrapped symmetric key and unwraps it, returning a symmetric - * key handle. Please note that the actual unwrapped key data may not be allowed to leave - * a hardware token... - */ -PK11SymKey * -NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOidTag bulkalgtag) -{ - /* that's easy */ - CK_MECHANISM_TYPE target; - PORT_Assert(bulkalgtag != SEC_OID_UNKNOWN); - target = PK11_AlgtagToMechanism(bulkalgtag); - if (bulkalgtag == SEC_OID_UNKNOWN || target == CKM_INVALID_MECHANISM) { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - return NULL; - } - return PK11_PubUnwrapSymKey(privkey, encKey, target, CKA_DECRYPT, 0); -} - -/* ====== MISSI (Fortezza) ========================================================== */ - -extern const SEC_ASN1Template NSS_SMIMEKEAParamTemplateAllParams[]; - -SECStatus -NSS_CMSUtil_EncryptSymKey_MISSI(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *bulkkey, - SECOidTag symalgtag, SECItem *encKey, SECItem **pparams, void *pwfn_arg) -{ - SECOidTag certalgtag; /* the certificate's encryption algorithm */ - SECOidTag encalgtag; /* the algorithm used for key exchange/agreement */ - SECStatus rv = SECFailure; - SECItem *params = NULL; - SECStatus err; - PK11SymKey *tek; - CERTCertificate *ourCert; - SECKEYPublicKey *ourPubKey, *publickey = NULL; - SECKEYPrivateKey *ourPrivKey = NULL; - NSSCMSKEATemplateSelector whichKEA = NSSCMSKEAInvalid; - NSSCMSSMIMEKEAParameters keaParams; - PLArenaPool *arena = NULL; - extern const SEC_ASN1Template *nss_cms_get_kea_template(NSSCMSKEATemplateSelector whichTemplate); - - /* Clear keaParams, since cleanup code checks the lengths */ - (void) memset(&keaParams, 0, sizeof(keaParams)); - - certalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); - PORT_Assert(certalgtag == SEC_OID_MISSI_KEA_DSS_OLD || - certalgtag == SEC_OID_MISSI_KEA_DSS || - certalgtag == SEC_OID_MISSI_KEA); - -#define SMIME_FORTEZZA_RA_LENGTH 128 -#define SMIME_FORTEZZA_IV_LENGTH 24 -#define SMIME_FORTEZZA_MAX_KEY_SIZE 256 - - /* We really want to show our KEA tag as the key exchange algorithm tag. */ - encalgtag = SEC_OID_NETSCAPE_SMIME_KEA; - - /* Get the public key of the recipient. */ - publickey = CERT_ExtractPublicKey(cert); - if (publickey == NULL) goto loser; - - /* Find our own cert, and extract its keys. */ - ourCert = PK11_FindBestKEAMatch(cert, pwfn_arg); - if (ourCert == NULL) goto loser; - - arena = PORT_NewArena(1024); - if (arena == NULL) - goto loser; - - ourPubKey = CERT_ExtractPublicKey(ourCert); - if (ourPubKey == NULL) { - CERT_DestroyCertificate(ourCert); - goto loser; - } - - /* While we're here, copy the public key into the outgoing - * KEA parameters. */ - SECITEM_CopyItem(arena, &(keaParams.originatorKEAKey), &(ourPubKey->u.fortezza.KEAKey)); - SECKEY_DestroyPublicKey(ourPubKey); - ourPubKey = NULL; - - /* Extract our private key in order to derive the KEA key. */ - ourPrivKey = PK11_FindKeyByAnyCert(ourCert, pwfn_arg); - CERT_DestroyCertificate(ourCert); /* we're done with this */ - if (!ourPrivKey) - goto loser; - - /* Prepare raItem with 128 bytes (filled with zeros). */ - keaParams.originatorRA.data = (unsigned char *)PORT_ArenaAlloc(arena,SMIME_FORTEZZA_RA_LENGTH); - keaParams.originatorRA.len = SMIME_FORTEZZA_RA_LENGTH; - - /* Generate the TEK (token exchange key) which we use - * to wrap the bulk encryption key. (keaparams.originatorRA) will be - * filled with a random seed which we need to send to - * the recipient. (user keying material in RFC2630/DSA speak) */ - tek = PK11_PubDerive(ourPrivKey, publickey, PR_TRUE, - &keaParams.originatorRA, NULL, - CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP, - CKA_WRAP, 0, pwfn_arg); - - SECKEY_DestroyPublicKey(publickey); - SECKEY_DestroyPrivateKey(ourPrivKey); - publickey = NULL; - ourPrivKey = NULL; - - if (!tek) - goto loser; - - /* allocate space for the wrapped key data */ - encKey->data = (unsigned char *)PORT_ArenaAlloc(poolp, SMIME_FORTEZZA_MAX_KEY_SIZE); - encKey->len = SMIME_FORTEZZA_MAX_KEY_SIZE; - - if (encKey->data == NULL) { - PK11_FreeSymKey(tek); - goto loser; - } - - /* Wrap the bulk key. What we do with the resulting data - depends on whether we're using Skipjack to wrap the key. */ - switch (PK11_AlgtagToMechanism(symalgtag)) { - case CKM_SKIPJACK_CBC64: - case CKM_SKIPJACK_ECB64: - case CKM_SKIPJACK_OFB64: - case CKM_SKIPJACK_CFB64: - case CKM_SKIPJACK_CFB32: - case CKM_SKIPJACK_CFB16: - case CKM_SKIPJACK_CFB8: - /* SKIPJACK, we use the wrap mechanism because we can do it on the hardware */ - err = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, bulkkey, encKey); - whichKEA = NSSCMSKEAUsesSkipjack; - break; - default: - /* Not SKIPJACK, we encrypt the raw key data */ - keaParams.nonSkipjackIV.data = - (unsigned char *)PORT_ArenaAlloc(arena, SMIME_FORTEZZA_IV_LENGTH); - keaParams.nonSkipjackIV.len = SMIME_FORTEZZA_IV_LENGTH; - err = PK11_WrapSymKey(CKM_SKIPJACK_CBC64, &keaParams.nonSkipjackIV, tek, bulkkey, encKey); - if (err != SECSuccess) - goto loser; - - if (encKey->len != PK11_GetKeyLength(bulkkey)) { - /* The size of the encrypted key is not the same as - that of the original bulk key, presumably due to - padding. Encode and store the real size of the - bulk key. */ - if (SEC_ASN1EncodeInteger(arena, &keaParams.bulkKeySize, PK11_GetKeyLength(bulkkey)) == NULL) - err = (SECStatus)PORT_GetError(); - else - /* use full template for encoding */ - whichKEA = NSSCMSKEAUsesNonSkipjackWithPaddedEncKey; - } - else - /* enc key length == bulk key length */ - whichKEA = NSSCMSKEAUsesNonSkipjack; - break; - } - - PK11_FreeSymKey(tek); - - if (err != SECSuccess) - goto loser; - - PORT_Assert(whichKEA != NSSCMSKEAInvalid); - - /* Encode the KEA parameters into the recipient info. */ - params = SEC_ASN1EncodeItem(poolp, NULL, &keaParams, nss_cms_get_kea_template(whichKEA)); - if (params == NULL) - goto loser; - - /* pass back the algorithm params */ - *pparams = params; - - rv = SECSuccess; - -loser: - if (arena) - PORT_FreeArena(arena, PR_FALSE); - if (publickey) - SECKEY_DestroyPublicKey(publickey); - if (ourPrivKey) - SECKEY_DestroyPrivateKey(ourPrivKey); - return rv; -} - -PK11SymKey * -NSS_CMSUtil_DecryptSymKey_MISSI(SECKEYPrivateKey *privkey, SECItem *encKey, SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg) -{ - /* fortezza: do a key exchange */ - SECStatus err; - CK_MECHANISM_TYPE bulkType; - PK11SymKey *tek; - SECKEYPublicKey *originatorPubKey; - NSSCMSSMIMEKEAParameters keaParams; - PK11SymKey *bulkkey; - int bulkLength; - - (void) memset(&keaParams, 0, sizeof(keaParams)); - - /* NOTE: this uses the SMIME v2 recipientinfo for compatibility. - All additional KEA parameters are DER-encoded in the encryption algorithm parameters */ - - /* Decode the KEA algorithm parameters. */ - err = SEC_ASN1DecodeItem(NULL, &keaParams, NSS_SMIMEKEAParamTemplateAllParams, - &(keyEncAlg->parameters)); - if (err != SECSuccess) - goto loser; - - /* get originator's public key */ - originatorPubKey = PK11_MakeKEAPubKey(keaParams.originatorKEAKey.data, - keaParams.originatorKEAKey.len); - if (originatorPubKey == NULL) - goto loser; - - /* Generate the TEK (token exchange key) which we use to unwrap the bulk encryption key. - The Derive function generates a shared secret and combines it with the originatorRA - data to come up with an unique session key */ - tek = PK11_PubDerive(privkey, originatorPubKey, PR_FALSE, - &keaParams.originatorRA, NULL, - CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP, - CKA_WRAP, 0, pwfn_arg); - SECKEY_DestroyPublicKey(originatorPubKey); /* not needed anymore */ - if (tek == NULL) - goto loser; - - /* Now that we have the TEK, unwrap the bulk key - with which to decrypt the message. We have to - do one of two different things depending on - whether Skipjack was used for *bulk* encryption - of the message. */ - bulkType = PK11_AlgtagToMechanism(bulkalgtag); - switch (bulkType) { - case CKM_SKIPJACK_CBC64: - case CKM_SKIPJACK_ECB64: - case CKM_SKIPJACK_OFB64: - case CKM_SKIPJACK_CFB64: - case CKM_SKIPJACK_CFB32: - case CKM_SKIPJACK_CFB16: - case CKM_SKIPJACK_CFB8: - /* Skipjack is being used as the bulk encryption algorithm.*/ - /* Unwrap the bulk key. */ - bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL, - encKey, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0); - break; - default: - /* Skipjack was not used for bulk encryption of this - message. Use Skipjack CBC64, with the nonSkipjackIV - part of the KEA key parameters, to decrypt - the bulk key. If the optional parameter bulkKeySize is present, - bulk key size is different than the encrypted key size */ - if (keaParams.bulkKeySize.len > 0) { - err = SEC_ASN1DecodeItem(NULL, &bulkLength, - SEC_ASN1_GET(SEC_IntegerTemplate), - &keaParams.bulkKeySize); - if (err != SECSuccess) - goto loser; - } - - bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_CBC64, &keaParams.nonSkipjackIV, - encKey, bulkType, CKA_DECRYPT, bulkLength); - break; - } - return bulkkey; -loser: - return NULL; -} - -/* ====== ESDH (Ephemeral-Static Diffie-Hellman) ==================================== */ - -SECStatus -NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key, - SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg, - SECItem *pubKey) -{ -#if 0 /* not yet done */ - SECOidTag certalgtag; /* the certificate's encryption algorithm */ - SECOidTag encalgtag; /* the algorithm used for key exchange/agreement */ - SECStatus rv; - SECItem *params = NULL; - int data_len; - SECStatus err; - PK11SymKey *tek; - CERTCertificate *ourCert; - SECKEYPublicKey *ourPubKey; - NSSCMSKEATemplateSelector whichKEA = NSSCMSKEAInvalid; - - certalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); - PORT_Assert(certalgtag == SEC_OID_X942_DIFFIE_HELMAN_KEY); - - /* We really want to show our KEA tag as the key exchange algorithm tag. */ - encalgtag = SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN; - - /* Get the public key of the recipient. */ - publickey = CERT_ExtractPublicKey(cert); - if (publickey == NULL) goto loser; - - /* XXXX generate a DH key pair on a PKCS11 module (XXX which parameters?) */ - /* XXXX */ourCert = PK11_FindBestKEAMatch(cert, wincx); - if (ourCert == NULL) goto loser; - - arena = PORT_NewArena(1024); - if (arena == NULL) goto loser; - - /* While we're here, extract the key pair's public key data and copy it into */ - /* the outgoing parameters. */ - /* XXXX */ourPubKey = CERT_ExtractPublicKey(ourCert); - if (ourPubKey == NULL) - { - goto loser; - } - SECITEM_CopyItem(arena, pubKey, /* XXX */&(ourPubKey->u.fortezza.KEAKey)); - SECKEY_DestroyPublicKey(ourPubKey); /* we only need the private key from now on */ - ourPubKey = NULL; - - /* Extract our private key in order to derive the KEA key. */ - ourPrivKey = PK11_FindKeyByAnyCert(ourCert,wincx); - CERT_DestroyCertificate(ourCert); /* we're done with this */ - if (!ourPrivKey) goto loser; - - /* If ukm desired, prepare it - allocate enough space (filled with zeros). */ - if (ukm) { - ukm->data = (unsigned char*)PORT_ArenaZAlloc(arena,/* XXXX */); - ukm->len = /* XXXX */; - } - - /* Generate the KEK (key exchange key) according to RFC2631 which we use - * to wrap the bulk encryption key. */ - kek = PK11_PubDerive(ourPrivKey, publickey, PR_TRUE, - ukm, NULL, - /* XXXX */CKM_KEA_KEY_DERIVE, /* XXXX */CKM_SKIPJACK_WRAP, - CKA_WRAP, 0, wincx); - - SECKEY_DestroyPublicKey(publickey); - SECKEY_DestroyPrivateKey(ourPrivKey); - publickey = NULL; - ourPrivKey = NULL; - - if (!kek) - goto loser; - - /* allocate space for the encrypted CEK (bulk key) */ - encKey->data = (unsigned char*)PORT_ArenaAlloc(poolp, SMIME_FORTEZZA_MAX_KEY_SIZE); - encKey->len = SMIME_FORTEZZA_MAX_KEY_SIZE; - - if (encKey->data == NULL) - { - PK11_FreeSymKey(kek); - goto loser; - } - - - /* Wrap the bulk key using CMSRC2WRAP or CMS3DESWRAP, depending on the */ - /* bulk encryption algorithm */ - switch (/* XXXX */PK11_AlgtagToMechanism(enccinfo->encalg)) - { - case /* XXXX */CKM_SKIPJACK_CFB8: - err = PK11_WrapSymKey(/* XXXX */CKM_CMS3DES_WRAP, NULL, kek, bulkkey, encKey); - whichKEA = NSSCMSKEAUsesSkipjack; - break; - case /* XXXX */CKM_SKIPJACK_CFB8: - err = PK11_WrapSymKey(/* XXXX */CKM_CMSRC2_WRAP, NULL, kek, bulkkey, encKey); - whichKEA = NSSCMSKEAUsesSkipjack; - break; - default: - /* XXXX what do we do here? Neither RC2 nor 3DES... */ - err = SECFailure; - /* set error */ - break; - } - - PK11_FreeSymKey(kek); /* we do not need the KEK anymore */ - if (err != SECSuccess) - goto loser; - - PORT_Assert(whichKEA != NSSCMSKEAInvalid); - - /* see RFC2630 12.3.1.1 "keyEncryptionAlgorithm must be ..." */ - /* params is the DER encoded key wrap algorithm (with parameters!) (XXX) */ - params = SEC_ASN1EncodeItem(arena, NULL, &keaParams, sec_pkcs7_get_kea_template(whichKEA)); - if (params == NULL) - goto loser; - - /* now set keyEncAlg */ - rv = SECOID_SetAlgorithmID(poolp, keyEncAlg, SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN, params); - if (rv != SECSuccess) - goto loser; - - /* XXXXXXX this is not right yet */ -loser: - if (arena) { - PORT_FreeArena(arena, PR_FALSE); - } - if (publickey) { - SECKEY_DestroyPublicKey(publickey); - } - if (ourPrivKey) { - SECKEY_DestroyPrivateKey(ourPrivKey); - } -#endif - return SECFailure; -} - -PK11SymKey * -NSS_CMSUtil_DecryptSymKey_ESDH(SECKEYPrivateKey *privkey, SECItem *encKey, SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg) -{ -#if 0 /* not yet done */ - SECStatus err; - CK_MECHANISM_TYPE bulkType; - PK11SymKey *tek; - SECKEYPublicKey *originatorPubKey; - NSSCMSSMIMEKEAParameters keaParams; - - /* XXXX get originator's public key */ - originatorPubKey = PK11_MakeKEAPubKey(keaParams.originatorKEAKey.data, - keaParams.originatorKEAKey.len); - if (originatorPubKey == NULL) - goto loser; - - /* Generate the TEK (token exchange key) which we use to unwrap the bulk encryption key. - The Derive function generates a shared secret and combines it with the originatorRA - data to come up with an unique session key */ - tek = PK11_PubDerive(privkey, originatorPubKey, PR_FALSE, - &keaParams.originatorRA, NULL, - CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP, - CKA_WRAP, 0, pwfn_arg); - SECKEY_DestroyPublicKey(originatorPubKey); /* not needed anymore */ - if (tek == NULL) - goto loser; - - /* Now that we have the TEK, unwrap the bulk key - with which to decrypt the message. */ - /* Skipjack is being used as the bulk encryption algorithm.*/ - /* Unwrap the bulk key. */ - bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL, - encKey, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0); - - return bulkkey; - -loser: -#endif - return NULL; -} - diff --git a/security/nss/lib/smime/cmsrecinfo.c b/security/nss/lib/smime/cmsrecinfo.c deleted file mode 100644 index 07236adc1..000000000 --- a/security/nss/lib/smime/cmsrecinfo.c +++ /dev/null @@ -1,743 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS recipientInfo methods. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "cert.h" -#include "key.h" -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "pk11func.h" -#include "secerr.h" - -PRBool -nss_cmsrecipientinfo_usessubjectkeyid(NSSCMSRecipientInfo *ri) -{ - if (ri->recipientInfoType == NSSCMSRecipientInfoID_KeyTrans) { - NSSCMSRecipientIdentifier *rid; - rid = &ri->ri.keyTransRecipientInfo.recipientIdentifier; - if (rid->identifierType == NSSCMSRecipientID_SubjectKeyID) { - return PR_TRUE; - } - } - return PR_FALSE; -} - -/* - * NOTE: fakeContent marks CMSMessage structure which is only used as a carrier - * of pwfn_arg and arena pools. In an ideal world, NSSCMSMessage would not have - * been exported, and we would have added an ordinary enum to handle this - * check. Unfortunatly wo don't have that luxury so we are overloading the - * contentTypeTag field. NO code should every try to interpret this content tag - * as a real OID tag, or use any fields other than pwfn_arg or poolp of this - * CMSMessage for that matter */ -static const SECOidData fakeContent; -NSSCMSRecipientInfo * -nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type, - CERTCertificate *cert, SECKEYPublicKey *pubKey, - SECItem *subjKeyID, void* pwfn_arg, SECItem* DERinput) -{ - NSSCMSRecipientInfo *ri; - void *mark; - SECOidTag certalgtag; - SECStatus rv = SECSuccess; - NSSCMSRecipientEncryptedKey *rek; - NSSCMSOriginatorIdentifierOrKey *oiok; - unsigned long version; - SECItem *dummy; - PLArenaPool *poolp; - CERTSubjectPublicKeyInfo *spki, *freeSpki = NULL; - NSSCMSRecipientIdentifier *rid; - extern const SEC_ASN1Template NSSCMSRecipientInfoTemplate[]; - - if (!cmsg) { - /* a CMSMessage wasn't supplied, create a fake one to hold the pwfunc - * and a private arena pool */ - cmsg = NSS_CMSMessage_Create(NULL); - cmsg->pwfn_arg = pwfn_arg; - /* mark it as a special cms message */ - cmsg->contentInfo.contentTypeTag = &fakeContent; - } - - poolp = cmsg->poolp; - - mark = PORT_ArenaMark(poolp); - - ri = (NSSCMSRecipientInfo *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSRecipientInfo)); - if (ri == NULL) - goto loser; - - ri->cmsg = cmsg; - - if (DERinput) { - /* decode everything from DER */ - SECItem newinput; - SECStatus rv = SECITEM_CopyItem(poolp, &newinput, DERinput); - if (SECSuccess != rv) - goto loser; - rv = SEC_QuickDERDecodeItem(poolp, ri, NSSCMSRecipientInfoTemplate, &newinput); - if (SECSuccess != rv) - goto loser; - } - - switch (type) { - case NSSCMSRecipientID_IssuerSN: - { - ri->cert = CERT_DupCertificate(cert); - if (NULL == ri->cert) - goto loser; - spki = &(cert->subjectPublicKeyInfo); - break; - } - - case NSSCMSRecipientID_SubjectKeyID: - { - PORT_Assert(pubKey); - spki = freeSpki = SECKEY_CreateSubjectPublicKeyInfo(pubKey); - break; - } - - case NSSCMSRecipientID_BrandNew: - goto done; - break; - - default: - /* unkown type */ - goto loser; - break; - } - - certalgtag = SECOID_GetAlgorithmTag(&(spki->algorithm)); - - rid = &ri->ri.keyTransRecipientInfo.recipientIdentifier; - switch (certalgtag) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - ri->recipientInfoType = NSSCMSRecipientInfoID_KeyTrans; - rid->identifierType = type; - if (type == NSSCMSRecipientID_IssuerSN) { - rid->id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert); - if (rid->id.issuerAndSN == NULL) { - break; - } - } else if (type == NSSCMSRecipientID_SubjectKeyID){ - NSSCMSKeyTransRecipientInfoEx *riExtra; - - rid->id.subjectKeyID = PORT_ArenaNew(poolp, SECItem); - if (rid->id.subjectKeyID == NULL) { - rv = SECFailure; - PORT_SetError(SEC_ERROR_NO_MEMORY); - break; - } - SECITEM_CopyItem(poolp, rid->id.subjectKeyID, subjKeyID); - if (rid->id.subjectKeyID->data == NULL) { - rv = SECFailure; - PORT_SetError(SEC_ERROR_NO_MEMORY); - break; - } - riExtra = &ri->ri.keyTransRecipientInfoEx; - riExtra->version = 0; - riExtra->pubKey = SECKEY_CopyPublicKey(pubKey); - if (riExtra->pubKey == NULL) { - rv = SECFailure; - PORT_SetError(SEC_ERROR_NO_MEMORY); - break; - } - } else { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - rv = SECFailure; - } - break; - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_KEA: - PORT_Assert(type == NSSCMSRecipientID_IssuerSN); - if (type != NSSCMSRecipientID_IssuerSN) { - rv = SECFailure; - break; - } - /* backward compatibility - this is not really a keytrans operation */ - ri->recipientInfoType = NSSCMSRecipientInfoID_KeyTrans; - /* hardcoded issuerSN choice for now */ - ri->ri.keyTransRecipientInfo.recipientIdentifier.identifierType = NSSCMSRecipientID_IssuerSN; - ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert); - if (ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN == NULL) { - rv = SECFailure; - break; - } - break; - case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */ - PORT_Assert(type == NSSCMSRecipientID_IssuerSN); - if (type != NSSCMSRecipientID_IssuerSN) { - rv = SECFailure; - break; - } - /* a key agreement op */ - ri->recipientInfoType = NSSCMSRecipientInfoID_KeyAgree; - - if (ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN == NULL) { - rv = SECFailure; - break; - } - /* we do not support the case where multiple recipients - * share the same KeyAgreeRecipientInfo and have multiple RecipientEncryptedKeys - * in this case, we would need to walk all the recipientInfos, take the - * ones that do KeyAgreement algorithms and join them, algorithm by algorithm - * Then, we'd generate ONE ukm and OriginatorIdentifierOrKey */ - - /* only epheremal-static Diffie-Hellman is supported for now - * this is the only form of key agreement that provides potential anonymity - * of the sender, plus we do not have to include certs in the message */ - - /* force single recipientEncryptedKey for now */ - if ((rek = NSS_CMSRecipientEncryptedKey_Create(poolp)) == NULL) { - rv = SECFailure; - break; - } - - /* hardcoded IssuerSN choice for now */ - rek->recipientIdentifier.identifierType = NSSCMSKeyAgreeRecipientID_IssuerSN; - if ((rek->recipientIdentifier.id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert)) == NULL) { - rv = SECFailure; - break; - } - - oiok = &(ri->ri.keyAgreeRecipientInfo.originatorIdentifierOrKey); - - /* see RFC2630 12.3.1.1 */ - oiok->identifierType = NSSCMSOriginatorIDOrKey_OriginatorPublicKey; - - rv = NSS_CMSArray_Add(poolp, (void ***)&ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys, - (void *)rek); - - break; - default: - /* other algorithms not supported yet */ - /* NOTE that we do not support any KEK algorithm */ - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - rv = SECFailure; - break; - } - - if (rv == SECFailure) - goto loser; - - /* set version */ - switch (ri->recipientInfoType) { - case NSSCMSRecipientInfoID_KeyTrans: - if (ri->ri.keyTransRecipientInfo.recipientIdentifier.identifierType == NSSCMSRecipientID_IssuerSN) - version = NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_ISSUERSN; - else - version = NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_SUBJKEY; - dummy = SEC_ASN1EncodeInteger(poolp, &(ri->ri.keyTransRecipientInfo.version), version); - if (dummy == NULL) - goto loser; - break; - case NSSCMSRecipientInfoID_KeyAgree: - dummy = SEC_ASN1EncodeInteger(poolp, &(ri->ri.keyAgreeRecipientInfo.version), - NSS_CMS_KEYAGREE_RECIPIENT_INFO_VERSION); - if (dummy == NULL) - goto loser; - break; - case NSSCMSRecipientInfoID_KEK: - /* NOTE: this cannot happen as long as we do not support any KEK algorithm */ - dummy = SEC_ASN1EncodeInteger(poolp, &(ri->ri.kekRecipientInfo.version), - NSS_CMS_KEK_RECIPIENT_INFO_VERSION); - if (dummy == NULL) - goto loser; - break; - - } - -done: - PORT_ArenaUnmark (poolp, mark); - if (freeSpki) - SECKEY_DestroySubjectPublicKeyInfo(freeSpki); - return ri; - -loser: - if (freeSpki) { - SECKEY_DestroySubjectPublicKeyInfo(freeSpki); - } - PORT_ArenaRelease (poolp, mark); - if (cmsg->contentInfo.contentTypeTag == &fakeContent) { - NSS_CMSMessage_Destroy(cmsg); - } - return NULL; -} - -/* - * NSS_CMSRecipientInfo_Create - create a recipientinfo - * - * we currently do not create KeyAgreement recipientinfos with multiple - * recipientEncryptedKeys the certificate is supposed to have been - * verified by the caller - */ -NSSCMSRecipientInfo * -NSS_CMSRecipientInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert) -{ - return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_IssuerSN, cert, - NULL, NULL, NULL, NULL); -} - -NSSCMSRecipientInfo * -NSS_CMSRecipientInfo_CreateNew(void* pwfn_arg) -{ - return nss_cmsrecipientinfo_create(NULL, NSSCMSRecipientID_BrandNew, NULL, - NULL, NULL, pwfn_arg, NULL); -} - -NSSCMSRecipientInfo * -NSS_CMSRecipientInfo_CreateFromDER(SECItem* input, void* pwfn_arg) -{ - return nss_cmsrecipientinfo_create(NULL, NSSCMSRecipientID_BrandNew, NULL, - NULL, NULL, pwfn_arg, input); -} - - -NSSCMSRecipientInfo * -NSS_CMSRecipientInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg, - SECItem *subjKeyID, - SECKEYPublicKey *pubKey) -{ - return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_SubjectKeyID, - NULL, pubKey, subjKeyID, NULL, NULL); -} - -NSSCMSRecipientInfo * -NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert(NSSCMSMessage *cmsg, - CERTCertificate *cert) -{ - SECKEYPublicKey *pubKey = NULL; - SECItem subjKeyID = {siBuffer, NULL, 0}; - NSSCMSRecipientInfo *retVal = NULL; - - if (!cmsg || !cert) { - return NULL; - } - pubKey = CERT_ExtractPublicKey(cert); - if (!pubKey) { - goto done; - } - if (CERT_FindSubjectKeyIDExtension(cert, &subjKeyID) != SECSuccess || - subjKeyID.data == NULL) { - goto done; - } - retVal = NSS_CMSRecipientInfo_CreateWithSubjKeyID(cmsg, &subjKeyID, pubKey); -done: - if (pubKey) - SECKEY_DestroyPublicKey(pubKey); - - if (subjKeyID.data) - SECITEM_FreeItem(&subjKeyID, PR_FALSE); - - return retVal; -} - -void -NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri) -{ - if (!ri) { - return; - } - /* version was allocated on the pool, so no need to destroy it */ - /* issuerAndSN was allocated on the pool, so no need to destroy it */ - if (ri->cert != NULL) - CERT_DestroyCertificate(ri->cert); - - if (nss_cmsrecipientinfo_usessubjectkeyid(ri)) { - NSSCMSKeyTransRecipientInfoEx *extra; - extra = &ri->ri.keyTransRecipientInfoEx; - if (extra->pubKey) - SECKEY_DestroyPublicKey(extra->pubKey); - } - if (ri->cmsg && ri->cmsg->contentInfo.contentTypeTag == &fakeContent) { - NSS_CMSMessage_Destroy(ri->cmsg); - } - - /* we're done. */ -} - -int -NSS_CMSRecipientInfo_GetVersion(NSSCMSRecipientInfo *ri) -{ - unsigned long version; - SECItem *versionitem = NULL; - - switch (ri->recipientInfoType) { - case NSSCMSRecipientInfoID_KeyTrans: - /* ignore subIndex */ - versionitem = &(ri->ri.keyTransRecipientInfo.version); - break; - case NSSCMSRecipientInfoID_KEK: - /* ignore subIndex */ - versionitem = &(ri->ri.kekRecipientInfo.version); - break; - case NSSCMSRecipientInfoID_KeyAgree: - versionitem = &(ri->ri.keyAgreeRecipientInfo.version); - break; - } - - PORT_Assert(versionitem); - if (versionitem == NULL) - return 0; - - /* always take apart the SECItem */ - if (SEC_ASN1DecodeInteger(versionitem, &version) != SECSuccess) - return 0; - else - return (int)version; -} - -SECItem * -NSS_CMSRecipientInfo_GetEncryptedKey(NSSCMSRecipientInfo *ri, int subIndex) -{ - SECItem *enckey = NULL; - - switch (ri->recipientInfoType) { - case NSSCMSRecipientInfoID_KeyTrans: - /* ignore subIndex */ - enckey = &(ri->ri.keyTransRecipientInfo.encKey); - break; - case NSSCMSRecipientInfoID_KEK: - /* ignore subIndex */ - enckey = &(ri->ri.kekRecipientInfo.encKey); - break; - case NSSCMSRecipientInfoID_KeyAgree: - enckey = &(ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[subIndex]->encKey); - break; - } - return enckey; -} - - -SECOidTag -NSS_CMSRecipientInfo_GetKeyEncryptionAlgorithmTag(NSSCMSRecipientInfo *ri) -{ - SECOidTag encalgtag = SEC_OID_UNKNOWN; /* an invalid encryption alg */ - - switch (ri->recipientInfoType) { - case NSSCMSRecipientInfoID_KeyTrans: - encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyTransRecipientInfo.keyEncAlg)); - break; - case NSSCMSRecipientInfoID_KeyAgree: - encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyAgreeRecipientInfo.keyEncAlg)); - break; - case NSSCMSRecipientInfoID_KEK: - encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.kekRecipientInfo.keyEncAlg)); - break; - } - return encalgtag; -} - -SECStatus -NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey, - SECOidTag bulkalgtag) -{ - CERTCertificate *cert; - SECOidTag certalgtag; - SECStatus rv = SECSuccess; - SECItem *params = NULL; - NSSCMSRecipientEncryptedKey *rek; - NSSCMSOriginatorIdentifierOrKey *oiok; - CERTSubjectPublicKeyInfo *spki, *freeSpki = NULL; - PLArenaPool *poolp; - NSSCMSKeyTransRecipientInfoEx *extra = NULL; - PRBool usesSubjKeyID; - - poolp = ri->cmsg->poolp; - cert = ri->cert; - usesSubjKeyID = nss_cmsrecipientinfo_usessubjectkeyid(ri); - if (cert) { - spki = &cert->subjectPublicKeyInfo; - certalgtag = SECOID_GetAlgorithmTag(&(spki->algorithm)); - } else if (usesSubjKeyID) { - extra = &ri->ri.keyTransRecipientInfoEx; - /* sanity check */ - PORT_Assert(extra->pubKey); - if (!extra->pubKey) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - spki = freeSpki = SECKEY_CreateSubjectPublicKeyInfo(extra->pubKey); - certalgtag = SECOID_GetAlgorithmTag(&spki->algorithm); - } else { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* XXX set ri->recipientInfoType to the proper value here */ - /* or should we look if it's been set already ? */ - - certalgtag = SECOID_GetAlgorithmTag(&spki->algorithm); - switch (certalgtag) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - /* wrap the symkey */ - if (cert) { - rv = NSS_CMSUtil_EncryptSymKey_RSA(poolp, cert, bulkkey, - &ri->ri.keyTransRecipientInfo.encKey); - if (rv != SECSuccess) - break; - } else if (usesSubjKeyID) { - PORT_Assert(extra != NULL); - rv = NSS_CMSUtil_EncryptSymKey_RSAPubKey(poolp, extra->pubKey, - bulkkey, &ri->ri.keyTransRecipientInfo.encKey); - if (rv != SECSuccess) - break; - } - - rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, NULL); - break; - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_KEA: - rv = NSS_CMSUtil_EncryptSymKey_MISSI(poolp, cert, bulkkey, - bulkalgtag, - &ri->ri.keyTransRecipientInfo.encKey, - ¶ms, ri->cmsg->pwfn_arg); - if (rv != SECSuccess) - break; - - /* here, we DO need to pass the params to the wrap function because, with - * RSA, there is no funny stuff going on with generation of IV vectors or so */ - rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, params); - break; - case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */ - rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[0]; - if (rek == NULL) { - rv = SECFailure; - break; - } - - oiok = &(ri->ri.keyAgreeRecipientInfo.originatorIdentifierOrKey); - PORT_Assert(oiok->identifierType == NSSCMSOriginatorIDOrKey_OriginatorPublicKey); - - /* see RFC2630 12.3.1.1 */ - if (SECOID_SetAlgorithmID(poolp, &oiok->id.originatorPublicKey.algorithmIdentifier, - SEC_OID_X942_DIFFIE_HELMAN_KEY, NULL) != SECSuccess) { - rv = SECFailure; - break; - } - - /* this will generate a key pair, compute the shared secret, */ - /* derive a key and ukm for the keyEncAlg out of it, encrypt the bulk key with */ - /* the keyEncAlg, set encKey, keyEncAlg, publicKey etc. */ - rv = NSS_CMSUtil_EncryptSymKey_ESDH(poolp, cert, bulkkey, - &rek->encKey, - &ri->ri.keyAgreeRecipientInfo.ukm, - &ri->ri.keyAgreeRecipientInfo.keyEncAlg, - &oiok->id.originatorPublicKey.publicKey); - - break; - default: - /* other algorithms not supported yet */ - /* NOTE that we do not support any KEK algorithm */ - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - rv = SECFailure; - break; - } - if (freeSpki) - SECKEY_DestroySubjectPublicKeyInfo(freeSpki); - - return rv; -} - -PK11SymKey * -NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex, - CERTCertificate *cert, SECKEYPrivateKey *privkey, SECOidTag bulkalgtag) -{ - PK11SymKey *bulkkey = NULL; - SECAlgorithmID *encalg; - SECOidTag encalgtag; - SECItem *enckey; - int error; - - ri->cert = CERT_DupCertificate(cert); - /* mark the recipientInfo so we can find it later */ - - switch (ri->recipientInfoType) { - case NSSCMSRecipientInfoID_KeyTrans: - encalg = &(ri->ri.keyTransRecipientInfo.keyEncAlg); - encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyTransRecipientInfo.keyEncAlg)); - enckey = &(ri->ri.keyTransRecipientInfo.encKey); /* ignore subIndex */ - switch (encalgtag) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - /* RSA encryption algorithm: */ - /* get the symmetric (bulk) key by unwrapping it using our private key */ - bulkkey = NSS_CMSUtil_DecryptSymKey_RSA(privkey, enckey, bulkalgtag); - break; - case SEC_OID_NETSCAPE_SMIME_KEA: - /* FORTEZZA key exchange algorithm */ - /* the supplemental data is in the parameters of encalg */ - bulkkey = NSS_CMSUtil_DecryptSymKey_MISSI(privkey, enckey, encalg, bulkalgtag, ri->cmsg->pwfn_arg); - break; - default: - error = SEC_ERROR_UNSUPPORTED_KEYALG; - goto loser; - } - break; - case NSSCMSRecipientInfoID_KeyAgree: - encalg = &(ri->ri.keyAgreeRecipientInfo.keyEncAlg); - encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyAgreeRecipientInfo.keyEncAlg)); - enckey = &(ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[subIndex]->encKey); - switch (encalgtag) { - case SEC_OID_X942_DIFFIE_HELMAN_KEY: - /* Diffie-Helman key exchange */ - /* XXX not yet implemented */ - /* XXX problem: SEC_OID_X942_DIFFIE_HELMAN_KEY points to a PKCS3 mechanism! */ - /* we support ephemeral-static DH only, so if the recipientinfo */ - /* has originator stuff in it, we punt (or do we? shouldn't be that hard...) */ - /* first, we derive the KEK (a symkey!) using a Derive operation, then we get the */ - /* content encryption key using a Unwrap op */ - /* the derive operation has to generate the key using the algorithm in RFC2631 */ - error = SEC_ERROR_UNSUPPORTED_KEYALG; - break; - default: - error = SEC_ERROR_UNSUPPORTED_KEYALG; - goto loser; - } - break; - case NSSCMSRecipientInfoID_KEK: - encalg = &(ri->ri.kekRecipientInfo.keyEncAlg); - encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.kekRecipientInfo.keyEncAlg)); - enckey = &(ri->ri.kekRecipientInfo.encKey); - /* not supported yet */ - error = SEC_ERROR_UNSUPPORTED_KEYALG; - goto loser; - break; - } - /* XXXX continue here */ - return bulkkey; - -loser: - return NULL; -} - -SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri, - CERTCertificate** retcert, - SECKEYPrivateKey** retkey) -{ - CERTCertificate* cert = NULL; - NSSCMSRecipient** recipients = NULL; - NSSCMSRecipientInfo* recipientInfos[2]; - SECStatus rv = SECSuccess; - SECKEYPrivateKey* key = NULL; - - if (!ri) - return SECFailure; - - if (!retcert && !retkey) { - /* nothing requested, nothing found, success */ - return SECSuccess; - } - - if (retcert) { - *retcert = NULL; - } - if (retkey) { - *retkey = NULL; - } - - if (ri->cert) { - cert = CERT_DupCertificate(ri->cert); - if (!cert) { - rv = SECFailure; - } - } - if (SECSuccess == rv && !cert) { - /* we don't have the cert, we have to look for it */ - /* first build an NSS_CMSRecipient */ - recipientInfos[0] = ri; - recipientInfos[1] = NULL; - - recipients = nss_cms_recipient_list_create(recipientInfos); - if (recipients) { - /* now look for the cert and key */ - if (0 == PK11_FindCertAndKeyByRecipientListNew(recipients, - ri->cmsg->pwfn_arg)) { - cert = CERT_DupCertificate(recipients[0]->cert); - key = SECKEY_CopyPrivateKey(recipients[0]->privkey); - } else { - rv = SECFailure; - } - - nss_cms_recipient_list_destroy(recipients); - } - else { - rv = SECFailure; - } - } else if (SECSuccess == rv && cert && retkey) { - /* we have the cert, we just need the key now */ - key = PK11_FindPrivateKeyFromCert(cert->slot, cert, ri->cmsg->pwfn_arg); - } - if (retcert) { - *retcert = cert; - } else { - if (cert) { - CERT_DestroyCertificate(cert); - } - } - if (retkey) { - *retkey = key; - } else { - if (key) { - SECKEY_DestroyPrivateKey(key); - } - } - - return rv; -} - -SECStatus NSS_CMSRecipientInfo_Encode(PRArenaPool* poolp, - const NSSCMSRecipientInfo *src, - SECItem* returned) -{ - extern const SEC_ASN1Template NSSCMSRecipientInfoTemplate[]; - SECStatus rv = SECFailure; - if (!src || !returned) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - } else if (SEC_ASN1EncodeItem(poolp, returned, src, - NSSCMSRecipientInfoTemplate)) { - rv = SECSuccess; - } - return rv; -} diff --git a/security/nss/lib/smime/cmsreclist.c b/security/nss/lib/smime/cmsreclist.c deleted file mode 100644 index 34e31d582..000000000 --- a/security/nss/lib/smime/cmsreclist.c +++ /dev/null @@ -1,193 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS recipient list functions - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "cert.h" -#include "key.h" -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "pk11func.h" -#include "prtime.h" -#include "secerr.h" - -static int -nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, NSSCMSRecipient **recipient_list) -{ - int count = 0; - int rlindex = 0; - int i, j; - NSSCMSRecipient *rle; - NSSCMSRecipientInfo *ri; - NSSCMSRecipientEncryptedKey *rek; - - for (i = 0; recipientinfos[i] != NULL; i++) { - ri = recipientinfos[i]; - switch (ri->recipientInfoType) { - case NSSCMSRecipientInfoID_KeyTrans: - if (recipient_list) { - /* alloc one & fill it out */ - rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient)); - if (rle == NULL) - return -1; - - rle->riIndex = i; - rle->subIndex = -1; - switch (ri->ri.keyTransRecipientInfo.recipientIdentifier.identifierType) { - case NSSCMSRecipientID_IssuerSN: - rle->kind = RLIssuerSN; - rle->id.issuerAndSN = ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN; - break; - case NSSCMSRecipientID_SubjectKeyID: - rle->kind = RLSubjKeyID; - rle->id.subjectKeyID = ri->ri.keyTransRecipientInfo.recipientIdentifier.id.subjectKeyID; - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return -1; - } - recipient_list[rlindex++] = rle; - } else { - count++; - } - break; - case NSSCMSRecipientInfoID_KeyAgree: - if (ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys == NULL) - break; - for (j=0; ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j] != NULL; j++) { - if (recipient_list) { - rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j]; - /* alloc one & fill it out */ - rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient)); - if (rle == NULL) - return -1; - - rle->riIndex = i; - rle->subIndex = j; - switch (rek->recipientIdentifier.identifierType) { - case NSSCMSKeyAgreeRecipientID_IssuerSN: - rle->kind = RLIssuerSN; - rle->id.issuerAndSN = rek->recipientIdentifier.id.issuerAndSN; - break; - case NSSCMSKeyAgreeRecipientID_RKeyID: - rle->kind = RLSubjKeyID; - rle->id.subjectKeyID = rek->recipientIdentifier.id.recipientKeyIdentifier.subjectKeyIdentifier; - break; - } - recipient_list[rlindex++] = rle; - } else { - count++; - } - } - break; - case NSSCMSRecipientInfoID_KEK: - /* KEK is not implemented */ - break; - } - } - /* if we have a recipient list, we return on success (-1, above, on failure) */ - /* otherwise, we return the count. */ - if (recipient_list) { - recipient_list[rlindex] = NULL; - return 0; - } else { - return count; - } -} - -NSSCMSRecipient ** -nss_cms_recipient_list_create(NSSCMSRecipientInfo **recipientinfos) -{ - int count, rv; - NSSCMSRecipient **recipient_list; - - /* count the number of recipient identifiers */ - count = nss_cms_recipients_traverse(recipientinfos, NULL); - if (count <= 0) { - /* no recipients? */ - PORT_SetError(SEC_ERROR_BAD_DATA); -#if 0 - PORT_SetErrorString("Cannot find recipient data in envelope."); -#endif - return NULL; - } - - /* allocate an array of pointers */ - recipient_list = (NSSCMSRecipient **) - PORT_ZAlloc((count + 1) * sizeof(NSSCMSRecipient *)); - if (recipient_list == NULL) - return NULL; - - /* now fill in the recipient_list */ - rv = nss_cms_recipients_traverse(recipientinfos, recipient_list); - if (rv < 0) { - nss_cms_recipient_list_destroy(recipient_list); - return NULL; - } - return recipient_list; -} - -void -nss_cms_recipient_list_destroy(NSSCMSRecipient **recipient_list) -{ - int i; - NSSCMSRecipient *recipient; - - for (i=0; recipient_list[i] != NULL; i++) { - recipient = recipient_list[i]; - if (recipient->cert) - CERT_DestroyCertificate(recipient->cert); - if (recipient->privkey) - SECKEY_DestroyPrivateKey(recipient->privkey); - if (recipient->slot) - PK11_FreeSlot(recipient->slot); - PORT_Free(recipient); - } - PORT_Free(recipient_list); -} - -NSSCMSRecipientEncryptedKey * -NSS_CMSRecipientEncryptedKey_Create(PLArenaPool *poolp) -{ - return (NSSCMSRecipientEncryptedKey *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSRecipientEncryptedKey)); -} diff --git a/security/nss/lib/smime/cmsreclist.h b/security/nss/lib/smime/cmsreclist.h deleted file mode 100644 index ba3f39eda..000000000 --- a/security/nss/lib/smime/cmsreclist.h +++ /dev/null @@ -1,62 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * $Id$ - */ - -#ifndef _CMSRECLIST_H -#define _CMSRECLIST_H - -struct NSSCMSRecipientStr { - int riIndex; /* this recipient's index in recipientInfo array */ - int subIndex; /* index into recipientEncryptedKeys */ - /* (only in NSSCMSKeyAgreeRecipientInfoStr) */ - enum {RLIssuerSN=0, RLSubjKeyID=1} kind; /* for conversion recipientinfos -> recipientlist */ - union { - CERTIssuerAndSN * issuerAndSN; - SECItem * subjectKeyID; - } id; - - /* result data (filled out for each recipient that's us) */ - CERTCertificate * cert; - SECKEYPrivateKey * privkey; - PK11SlotInfo * slot; -}; - -typedef struct NSSCMSRecipientStr NSSCMSRecipient; - -#endif /* _CMSRECLIST_H */ diff --git a/security/nss/lib/smime/cmssigdata.c b/security/nss/lib/smime/cmssigdata.c deleted file mode 100644 index 0ba771d65..000000000 --- a/security/nss/lib/smime/cmssigdata.c +++ /dev/null @@ -1,1146 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS signedData methods. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "cert.h" -/*#include "cdbhdl.h"*/ -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "pk11func.h" -#include "secerr.h" - -NSSCMSSignedData * -NSS_CMSSignedData_Create(NSSCMSMessage *cmsg) -{ - void *mark; - NSSCMSSignedData *sigd; - PLArenaPool *poolp; - - if (!cmsg) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - - poolp = cmsg->poolp; - - mark = PORT_ArenaMark(poolp); - - sigd = (NSSCMSSignedData *)PORT_ArenaZAlloc (poolp, sizeof(NSSCMSSignedData)); - if (sigd == NULL) - goto loser; - - sigd->cmsg = cmsg; - - /* signerInfos, certs, certlists, crls are all empty */ - /* version is set in NSS_CMSSignedData_Finalize() */ - - PORT_ArenaUnmark(poolp, mark); - return sigd; - -loser: - PORT_ArenaRelease(poolp, mark); - return NULL; -} - -void -NSS_CMSSignedData_Destroy(NSSCMSSignedData *sigd) -{ - CERTCertificate **certs, **tempCerts, *cert; - CERTCertificateList **certlists, *certlist; - NSSCMSSignerInfo **signerinfos, *si; - - if (sigd == NULL) - return; - - certs = sigd->certs; - tempCerts = sigd->tempCerts; - certlists = sigd->certLists; - signerinfos = sigd->signerInfos; - - if (certs != NULL) { - while ((cert = *certs++) != NULL) - CERT_DestroyCertificate (cert); - } - - if (tempCerts != NULL) { - while ((cert = *tempCerts++) != NULL) - CERT_DestroyCertificate (cert); - } - - if (certlists != NULL) { - while ((certlist = *certlists++) != NULL) - CERT_DestroyCertificateList (certlist); - } - - if (signerinfos != NULL) { - while ((si = *signerinfos++) != NULL) - NSS_CMSSignerInfo_Destroy(si); - } - - /* everything's in a pool, so don't worry about the storage */ - NSS_CMSContentInfo_Destroy(&(sigd->contentInfo)); - -} - -/* - * NSS_CMSSignedData_Encode_BeforeStart - do all the necessary things to a SignedData - * before start of encoding. - * - * In detail: - * - find out about the right value to put into sigd->version - * - come up with a list of digestAlgorithms (which should be the union of the algorithms - * in the signerinfos). - * If we happen to have a pre-set list of algorithms (and digest values!), we - * check if we have all the signerinfos' algorithms. If not, this is an error. - */ -SECStatus -NSS_CMSSignedData_Encode_BeforeStart(NSSCMSSignedData *sigd) -{ - NSSCMSSignerInfo *signerinfo; - SECOidTag digestalgtag; - SECItem *dummy; - int version; - SECStatus rv; - PRBool haveDigests = PR_FALSE; - int n, i; - PLArenaPool *poolp; - - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - poolp = sigd->cmsg->poolp; - - /* we assume that we have precomputed digests if there is a list of algorithms, and */ - /* a chunk of data for each of those algorithms */ - if (sigd->digestAlgorithms != NULL && sigd->digests != NULL) { - for (i=0; sigd->digestAlgorithms[i] != NULL; i++) { - if (sigd->digests[i] == NULL) - break; - } - if (sigd->digestAlgorithms[i] == NULL) /* reached the end of the array? */ - haveDigests = PR_TRUE; /* yes: we must have all the digests */ - } - - version = NSS_CMS_SIGNED_DATA_VERSION_BASIC; - - /* RFC2630 5.1 "version is the syntax version number..." */ - if (NSS_CMSContentInfo_GetContentTypeTag(&(sigd->contentInfo)) != SEC_OID_PKCS7_DATA) - version = NSS_CMS_SIGNED_DATA_VERSION_EXT; - - /* prepare all the SignerInfos (there may be none) */ - for (i=0; i < NSS_CMSSignedData_SignerInfoCount(sigd); i++) { - signerinfo = NSS_CMSSignedData_GetSignerInfo(sigd, i); - - /* RFC2630 5.1 "version is the syntax version number..." */ - if (NSS_CMSSignerInfo_GetVersion(signerinfo) != NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN) - version = NSS_CMS_SIGNED_DATA_VERSION_EXT; - - /* collect digestAlgorithms from SignerInfos */ - /* (we need to know which algorithms we have when the content comes in) */ - /* do not overwrite any existing digestAlgorithms (and digest) */ - digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo); - n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); - if (n < 0 && haveDigests) { - /* oops, there is a digestalg we do not have a digest for */ - /* but we were supposed to have all the digests already... */ - goto loser; - } else if (n < 0) { - /* add the digestAlgorithm & a NULL digest */ - rv = NSS_CMSSignedData_AddDigest(poolp, sigd, digestalgtag, NULL); - if (rv != SECSuccess) - goto loser; - } else { - /* found it, nothing to do */ - } - } - - dummy = SEC_ASN1EncodeInteger(poolp, &(sigd->version), (long)version); - if (dummy == NULL) - return SECFailure; - - /* this is a SET OF, so we need to sort them guys */ - rv = NSS_CMSArray_SortByDER((void **)sigd->digestAlgorithms, - SEC_ASN1_GET(SECOID_AlgorithmIDTemplate), - (void **)sigd->digests); - if (rv != SECSuccess) - return SECFailure; - - return SECSuccess; - -loser: - return SECFailure; -} - -SECStatus -NSS_CMSSignedData_Encode_BeforeData(NSSCMSSignedData *sigd) -{ - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - /* set up the digests */ - if (sigd->digests && sigd->digests[0]) { - sigd->contentInfo.digcx = NULL; /* don't attempt to make new ones. */ - } else if (sigd->digestAlgorithms != NULL) { - sigd->contentInfo.digcx = - NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms); - if (sigd->contentInfo.digcx == NULL) - return SECFailure; - } - return SECSuccess; -} - -/* - * NSS_CMSSignedData_Encode_AfterData - do all the necessary things to a SignedData - * after all the encapsulated data was passed through the encoder. - * - * In detail: - * - create the signatures in all the SignerInfos - * - * Please note that nothing is done to the Certificates and CRLs in the message - this - * is entirely the responsibility of our callers. - */ -SECStatus -NSS_CMSSignedData_Encode_AfterData(NSSCMSSignedData *sigd) -{ - NSSCMSSignerInfo **signerinfos, *signerinfo; - NSSCMSContentInfo *cinfo; - SECOidTag digestalgtag; - SECStatus ret = SECFailure; - SECStatus rv; - SECItem *contentType; - int certcount; - int i, ci, cli, n, rci, si; - PLArenaPool *poolp; - CERTCertificateList *certlist; - extern const SEC_ASN1Template NSSCMSSignerInfoTemplate[]; - - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - poolp = sigd->cmsg->poolp; - cinfo = &(sigd->contentInfo); - - /* did we have digest calculation going on? */ - if (cinfo->digcx) { - rv = NSS_CMSDigestContext_FinishMultiple(cinfo->digcx, poolp, - &(sigd->digests)); - /* error has been set by NSS_CMSDigestContext_FinishMultiple */ - cinfo->digcx = NULL; - if (rv != SECSuccess) - goto loser; - } - - signerinfos = sigd->signerInfos; - certcount = 0; - - /* prepare all the SignerInfos (there may be none) */ - for (i=0; i < NSS_CMSSignedData_SignerInfoCount(sigd); i++) { - signerinfo = NSS_CMSSignedData_GetSignerInfo(sigd, i); - - /* find correct digest for this signerinfo */ - digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo); - n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); - if (n < 0 || sigd->digests == NULL || sigd->digests[n] == NULL) { - /* oops - digest not found */ - PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND); - goto loser; - } - - /* XXX if our content is anything else but data, we need to force the - * presence of signed attributes (RFC2630 5.3 "signedAttributes is a - * collection...") */ - - /* pass contentType here as we want a contentType attribute */ - if ((contentType = NSS_CMSContentInfo_GetContentTypeOID(cinfo)) == NULL) - goto loser; - - /* sign the thing */ - rv = NSS_CMSSignerInfo_Sign(signerinfo, sigd->digests[n], contentType); - if (rv != SECSuccess) - goto loser; - - /* while we're at it, count number of certs in certLists */ - certlist = NSS_CMSSignerInfo_GetCertList(signerinfo); - if (certlist) - certcount += certlist->len; - } - - /* this is a SET OF, so we need to sort them guys */ - rv = NSS_CMSArray_SortByDER((void **)signerinfos, NSSCMSSignerInfoTemplate, NULL); - if (rv != SECSuccess) - goto loser; - - /* - * now prepare certs & crls - */ - - /* count the rest of the certs */ - if (sigd->certs != NULL) { - for (ci = 0; sigd->certs[ci] != NULL; ci++) - certcount++; - } - - if (sigd->certLists != NULL) { - for (cli = 0; sigd->certLists[cli] != NULL; cli++) - certcount += sigd->certLists[cli]->len; - } - - if (certcount == 0) { - sigd->rawCerts = NULL; - } else { - /* - * Combine all of the certs and cert chains into rawcerts. - * Note: certcount is an upper bound; we may not need that many slots - * but we will allocate anyway to avoid having to do another pass. - * (The temporary space saving is not worth it.) - * - * XXX ARGH - this NEEDS to be fixed. need to come up with a decent - * SetOfDERcertficates implementation - */ - sigd->rawCerts = (SECItem **)PORT_ArenaAlloc(poolp, (certcount + 1) * sizeof(SECItem *)); - if (sigd->rawCerts == NULL) - return SECFailure; - - /* - * XXX Want to check for duplicates and not add *any* cert that is - * already in the set. This will be more important when we start - * dealing with larger sets of certs, dual-key certs (signing and - * encryption), etc. For the time being we can slide by... - * - * XXX ARGH - this NEEDS to be fixed. need to come up with a decent - * SetOfDERcertficates implementation - */ - rci = 0; - if (signerinfos != NULL) { - for (si = 0; signerinfos[si] != NULL; si++) { - signerinfo = signerinfos[si]; - for (ci = 0; ci < signerinfo->certList->len; ci++) - sigd->rawCerts[rci++] = &(signerinfo->certList->certs[ci]); - } - } - - if (sigd->certs != NULL) { - for (ci = 0; sigd->certs[ci] != NULL; ci++) - sigd->rawCerts[rci++] = &(sigd->certs[ci]->derCert); - } - - if (sigd->certLists != NULL) { - for (cli = 0; sigd->certLists[cli] != NULL; cli++) { - for (ci = 0; ci < sigd->certLists[cli]->len; ci++) - sigd->rawCerts[rci++] = &(sigd->certLists[cli]->certs[ci]); - } - } - - sigd->rawCerts[rci] = NULL; - - /* this is a SET OF, so we need to sort them guys - we have the DER already, though */ - NSS_CMSArray_Sort((void **)sigd->rawCerts, NSS_CMSUtil_DERCompare, NULL, NULL); - } - - ret = SECSuccess; - -loser: - return ret; -} - -SECStatus -NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd) -{ - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - /* set up the digests */ - if (sigd->digestAlgorithms != NULL && sigd->digests == NULL) { - /* if digests are already there, do nothing */ - sigd->contentInfo.digcx = NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms); - if (sigd->contentInfo.digcx == NULL) - return SECFailure; - } - return SECSuccess; -} - -/* - * NSS_CMSSignedData_Decode_AfterData - do all the necessary things to a - * SignedData after all the encapsulated data was passed through the decoder. - */ -SECStatus -NSS_CMSSignedData_Decode_AfterData(NSSCMSSignedData *sigd) -{ - SECStatus rv = SECSuccess; - - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* did we have digest calculation going on? */ - if (sigd->contentInfo.digcx) { - rv = NSS_CMSDigestContext_FinishMultiple(sigd->contentInfo.digcx, - sigd->cmsg->poolp, &(sigd->digests)); - /* error set by NSS_CMSDigestContext_FinishMultiple */ - sigd->contentInfo.digcx = NULL; - } - return rv; -} - -/* - * NSS_CMSSignedData_Decode_AfterEnd - do all the necessary things to a SignedData - * after all decoding is finished. - */ -SECStatus -NSS_CMSSignedData_Decode_AfterEnd(NSSCMSSignedData *sigd) -{ - NSSCMSSignerInfo **signerinfos = NULL; - int i; - - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* set cmsg for all the signerinfos */ - signerinfos = sigd->signerInfos; - - /* set cmsg for all the signerinfos */ - if (signerinfos) { - for (i = 0; signerinfos[i] != NULL; i++) - signerinfos[i]->cmsg = sigd->cmsg; - } - - return SECSuccess; -} - -/* - * NSS_CMSSignedData_GetSignerInfos - retrieve the SignedData's signer list - */ -NSSCMSSignerInfo ** -NSS_CMSSignedData_GetSignerInfos(NSSCMSSignedData *sigd) -{ - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - return sigd->signerInfos; -} - -int -NSS_CMSSignedData_SignerInfoCount(NSSCMSSignedData *sigd) -{ - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return 0; - } - return NSS_CMSArray_Count((void **)sigd->signerInfos); -} - -NSSCMSSignerInfo * -NSS_CMSSignedData_GetSignerInfo(NSSCMSSignedData *sigd, int i) -{ - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - return sigd->signerInfos[i]; -} - -/* - * NSS_CMSSignedData_GetDigestAlgs - retrieve the SignedData's digest algorithm list - */ -SECAlgorithmID ** -NSS_CMSSignedData_GetDigestAlgs(NSSCMSSignedData *sigd) -{ - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - return sigd->digestAlgorithms; -} - -/* - * NSS_CMSSignedData_GetContentInfo - return pointer to this signedData's contentinfo - */ -NSSCMSContentInfo * -NSS_CMSSignedData_GetContentInfo(NSSCMSSignedData *sigd) -{ - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - return &(sigd->contentInfo); -} - -/* - * NSS_CMSSignedData_GetCertificateList - retrieve the SignedData's certificate list - */ -SECItem ** -NSS_CMSSignedData_GetCertificateList(NSSCMSSignedData *sigd) -{ - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - return sigd->rawCerts; -} - -SECStatus -NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb, - SECCertUsage certusage, PRBool keepcerts) -{ - int certcount; - CERTCertificate **certArray = NULL; - CERTCertList *certList = NULL; - CERTCertListNode *node; - SECStatus rv; - SECItem **rawArray; - int i; - PRTime now; - - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - certcount = NSS_CMSArray_Count((void **)sigd->rawCerts); - - /* get the certs in the temp DB */ - rv = CERT_ImportCerts(certdb, certusage, certcount, sigd->rawCerts, - &certArray, PR_FALSE, PR_FALSE, NULL); - if (rv != SECSuccess) { - goto loser; - } - - /* save the certs so they don't get destroyed */ - for (i=0; i < certcount; i++) { - CERTCertificate *cert = certArray[i]; - if (cert) - NSS_CMSSignedData_AddTempCertificate(sigd, cert); - } - - if (!keepcerts) { - goto done; - } - - /* build a CertList for filtering */ - certList = CERT_NewCertList(); - if (certList == NULL) { - rv = SECFailure; - goto loser; - } - for (i=0; i < certcount; i++) { - CERTCertificate *cert = certArray[i]; - if (cert) - cert = CERT_DupCertificate(cert); - if (cert) - CERT_AddCertToListTail(certList,cert); - } - - /* filter out the certs we don't want */ - rv = CERT_FilterCertListByUsage(certList,certusage, PR_FALSE); - if (rv != SECSuccess) { - goto loser; - } - - /* go down the remaining list of certs and verify that they have - * valid chains, then import them. - */ - now = PR_Now(); - for (node = CERT_LIST_HEAD(certList) ; !CERT_LIST_END(node,certList); - node= CERT_LIST_NEXT(node)) { - CERTCertificateList *certChain; - - if (CERT_VerifyCert(certdb, node->cert, - PR_TRUE, certusage, now, NULL, NULL) != SECSuccess) { - continue; - } - - certChain = CERT_CertChainFromCert(node->cert, certusage, PR_FALSE); - if (!certChain) { - continue; - } - - /* - * CertChain returns an array of SECItems, import expects an array of - * SECItem pointers. Create the SECItem Pointers from the array of - * SECItems. - */ - rawArray = (SECItem **)PORT_Alloc(certChain->len*sizeof (SECItem *)); - if (!rawArray) { - CERT_DestroyCertificateList(certChain); - continue; - } - for (i=0; i < certChain->len; i++) { - rawArray[i] = &certChain->certs[i]; - } - (void )CERT_ImportCerts(certdb, certusage, certChain->len, - rawArray, NULL, keepcerts, PR_FALSE, NULL); - PORT_Free(rawArray); - CERT_DestroyCertificateList(certChain); - } - - rv = SECSuccess; - - /* XXX CRL handling */ - -done: - if (sigd->signerInfos != NULL) { - /* fill in all signerinfo's certs */ - for (i = 0; sigd->signerInfos[i] != NULL; i++) - (void)NSS_CMSSignerInfo_GetSigningCertificate( - sigd->signerInfos[i], certdb); - } - -loser: - /* now free everything */ - if (certArray) { - CERT_DestroyCertArray(certArray,certcount); - } - if (certList) { - CERT_DestroyCertList(certList); - } - - return rv; -} - -/* - * XXX the digests need to be passed in BETWEEN the decoding and the verification in case - * of external signatures! - */ - -/* - * NSS_CMSSignedData_VerifySignerInfo - check the signatures. - * - * The digests were either calculated during decoding (and are stored in the - * signedData itself) or set after decoding using NSS_CMSSignedData_SetDigests. - * - * The verification checks if the signing cert is valid and has a trusted chain - * for the purpose specified by "certusage". - */ -SECStatus -NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i, - CERTCertDBHandle *certdb, SECCertUsage certusage) -{ - NSSCMSSignerInfo *signerinfo; - NSSCMSContentInfo *cinfo; - SECOidData *algiddata; - SECItem *contentType, *digest; - SECOidTag oidTag; - SECStatus rv; - - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - cinfo = &(sigd->contentInfo); - - signerinfo = sigd->signerInfos[i]; - - /* verify certificate */ - rv = NSS_CMSSignerInfo_VerifyCertificate(signerinfo, certdb, certusage); - if (rv != SECSuccess) - return rv; /* error is set */ - - /* find digest and contentType for signerinfo */ - algiddata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo); - oidTag = algiddata ? algiddata->offset : SEC_OID_UNKNOWN; - digest = NSS_CMSSignedData_GetDigestValue(sigd, oidTag); - /* NULL digest is acceptable. */ - contentType = NSS_CMSContentInfo_GetContentTypeOID(cinfo); - /* NULL contentType is acceptable. */ - - /* now verify signature */ - rv = NSS_CMSSignerInfo_Verify(signerinfo, digest, contentType); - return rv; -} - -/* - * NSS_CMSSignedData_VerifyCertsOnly - verify the certs in a certs-only message - */ -SECStatus -NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd, - CERTCertDBHandle *certdb, - SECCertUsage usage) -{ - CERTCertificate *cert; - SECStatus rv = SECSuccess; - int i; - int count; - PRTime now; - - if (!sigd || !certdb || !sigd->rawCerts) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - count = NSS_CMSArray_Count((void**)sigd->rawCerts); - now = PR_Now(); - for (i=0; i < count; i++) { - if (sigd->certs && sigd->certs[i]) { - cert = CERT_DupCertificate(sigd->certs[i]); - } else { - cert = CERT_FindCertByDERCert(certdb, sigd->rawCerts[i]); - if (!cert) { - rv = SECFailure; - break; - } - } - rv |= CERT_VerifyCert(certdb, cert, PR_TRUE, usage, now, - NULL, NULL); - CERT_DestroyCertificate(cert); - } - - return rv; -} - -/* - * NSS_CMSSignedData_HasDigests - see if we have digests in place - */ -PRBool -NSS_CMSSignedData_HasDigests(NSSCMSSignedData *sigd) -{ - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return PR_FALSE; - } - return (sigd->digests != NULL); -} - -SECStatus -NSS_CMSSignedData_AddCertList(NSSCMSSignedData *sigd, CERTCertificateList *certlist) -{ - SECStatus rv; - - if (!sigd || !certlist) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* XXX memory?? a certlist has an arena of its own and is not refcounted!?!? */ - rv = NSS_CMSArray_Add(sigd->cmsg->poolp, (void ***)&(sigd->certLists), (void *)certlist); - - return rv; -} - -/* - * NSS_CMSSignedData_AddCertChain - add cert and its entire chain to the set of certs - */ -SECStatus -NSS_CMSSignedData_AddCertChain(NSSCMSSignedData *sigd, CERTCertificate *cert) -{ - CERTCertificateList *certlist; - SECCertUsage usage; - SECStatus rv; - - usage = certUsageEmailSigner; - - if (!sigd || !cert) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* do not include root */ - certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE); - if (certlist == NULL) - return SECFailure; - - rv = NSS_CMSSignedData_AddCertList(sigd, certlist); - - return rv; -} - -extern SECStatus -NSS_CMSSignedData_AddTempCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert) -{ - CERTCertificate *c; - SECStatus rv; - - if (!sigd || !cert) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - c = CERT_DupCertificate(cert); - rv = NSS_CMSArray_Add(sigd->cmsg->poolp, (void ***)&(sigd->tempCerts), (void *)c); - return rv; -} - -SECStatus -NSS_CMSSignedData_AddCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert) -{ - CERTCertificate *c; - SECStatus rv; - - if (!sigd || !cert) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - c = CERT_DupCertificate(cert); - rv = NSS_CMSArray_Add(sigd->cmsg->poolp, (void ***)&(sigd->certs), (void *)c); - return rv; -} - -PRBool -NSS_CMSSignedData_ContainsCertsOrCrls(NSSCMSSignedData *sigd) -{ - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return PR_FALSE; - } - if (sigd->rawCerts != NULL && sigd->rawCerts[0] != NULL) - return PR_TRUE; - else if (sigd->crls != NULL && sigd->crls[0] != NULL) - return PR_TRUE; - else - return PR_FALSE; -} - -SECStatus -NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd, - NSSCMSSignerInfo *signerinfo) -{ - void *mark; - SECStatus rv; - SECOidTag digestalgtag; - PLArenaPool *poolp; - - if (!sigd || !signerinfo) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - poolp = sigd->cmsg->poolp; - - mark = PORT_ArenaMark(poolp); - - /* add signerinfo */ - rv = NSS_CMSArray_Add(poolp, (void ***)&(sigd->signerInfos), (void *)signerinfo); - if (rv != SECSuccess) - goto loser; - - /* - * add empty digest - * Empty because we don't have it yet. Either it gets created during encoding - * (if the data is present) or has to be set externally. - * XXX maybe pass it in optionally? - */ - digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo); - rv = NSS_CMSSignedData_SetDigestValue(sigd, digestalgtag, NULL); - if (rv != SECSuccess) - goto loser; - - /* - * The last thing to get consistency would be adding the digest. - */ - - PORT_ArenaUnmark(poolp, mark); - return SECSuccess; - -loser: - PORT_ArenaRelease (poolp, mark); - return SECFailure; -} - -/* - * NSS_CMSSignedData_SetDigests - set a signedData's digests member - * - * "digestalgs" - array of digest algorithm IDs - * "digests" - array of digests corresponding to the digest algorithms - */ -SECStatus -NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd, - SECAlgorithmID **digestalgs, - SECItem **digests) -{ - int cnt, i, idx; - - if (!sigd || !digestalgs || !digests) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (sigd->digestAlgorithms == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* we assume that the digests array is just not there yet */ - PORT_Assert(sigd->digests == NULL); - if (sigd->digests != NULL) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - - /* now allocate one (same size as digestAlgorithms) */ - cnt = NSS_CMSArray_Count((void **)sigd->digestAlgorithms); - sigd->digests = PORT_ArenaZAlloc(sigd->cmsg->poolp, (cnt + 1) * sizeof(SECItem *)); - if (sigd->digests == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } - - for (i = 0; sigd->digestAlgorithms[i] != NULL; i++) { - /* try to find the sigd's i'th digest algorithm in the array we passed in */ - idx = NSS_CMSAlgArray_GetIndexByAlgID(digestalgs, sigd->digestAlgorithms[i]); - if (idx < 0) { - PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND); - return SECFailure; - } - if (!digests[idx]) { - /* We have no digest for this algorithm, probably because it is - ** unrecognized or unsupported. We'll ignore this here. If this - ** digest is needed later, an error will be be generated then. - */ - continue; - } - - /* found it - now set it */ - if ((sigd->digests[i] = SECITEM_AllocItem(sigd->cmsg->poolp, NULL, 0)) == NULL || - SECITEM_CopyItem(sigd->cmsg->poolp, sigd->digests[i], digests[idx]) != SECSuccess) - { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } - } - return SECSuccess; -} - -SECStatus -NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd, - SECOidTag digestalgtag, - SECItem *digestdata) -{ - SECItem *digest = NULL; - PLArenaPool *poolp; - void *mark; - int n, cnt; - - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - poolp = sigd->cmsg->poolp; - - mark = PORT_ArenaMark(poolp); - - - if (digestdata) { - digest = (SECItem *) PORT_ArenaZAlloc(poolp,sizeof(SECItem)); - - /* copy digestdata item to arena (in case we have it and are not only making room) */ - if (SECITEM_CopyItem(poolp, digest, digestdata) != SECSuccess) - goto loser; - } - - /* now allocate one (same size as digestAlgorithms) */ - if (sigd->digests == NULL) { - cnt = NSS_CMSArray_Count((void **)sigd->digestAlgorithms); - sigd->digests = PORT_ArenaZAlloc(sigd->cmsg->poolp, (cnt + 1) * sizeof(SECItem *)); - if (sigd->digests == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } - } - - n = -1; - if (sigd->digestAlgorithms != NULL) - n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); - - /* if not found, add a digest */ - if (n < 0) { - if (NSS_CMSSignedData_AddDigest(poolp, sigd, digestalgtag, digest) != SECSuccess) - goto loser; - } else { - /* replace NULL pointer with digest item (and leak previous value) */ - sigd->digests[n] = digest; - } - - PORT_ArenaUnmark(poolp, mark); - return SECSuccess; - -loser: - PORT_ArenaRelease(poolp, mark); - return SECFailure; -} - -SECStatus -NSS_CMSSignedData_AddDigest(PRArenaPool *poolp, - NSSCMSSignedData *sigd, - SECOidTag digestalgtag, - SECItem *digest) -{ - SECAlgorithmID *digestalg; - void *mark; - - if (!sigd || !poolp) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - mark = PORT_ArenaMark(poolp); - - digestalg = PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID)); - if (digestalg == NULL) - goto loser; - - if (SECOID_SetAlgorithmID (poolp, digestalg, digestalgtag, NULL) != SECSuccess) /* no params */ - goto loser; - - if (NSS_CMSArray_Add(poolp, (void ***)&(sigd->digestAlgorithms), (void *)digestalg) != SECSuccess || - /* even if digest is NULL, add dummy to have same-size array */ - NSS_CMSArray_Add(poolp, (void ***)&(sigd->digests), (void *)digest) != SECSuccess) - { - goto loser; - } - - PORT_ArenaUnmark(poolp, mark); - return SECSuccess; - -loser: - PORT_ArenaRelease(poolp, mark); - return SECFailure; -} - -/* XXX This function doesn't set the error code on failure. */ -SECItem * -NSS_CMSSignedData_GetDigestValue(NSSCMSSignedData *sigd, SECOidTag digestalgtag) -{ - int n; - - if (!sigd) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - - if (sigd->digestAlgorithms == NULL || sigd->digests == NULL) { - PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND); - return NULL; - } - - n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); - - return (n < 0) ? NULL : sigd->digests[n]; -} - -/* ============================================================================= - * Misc. utility functions - */ - -/* - * NSS_CMSSignedData_CreateCertsOnly - create a certs-only SignedData. - * - * cert - base certificates that will be included - * include_chain - if true, include the complete cert chain for cert - * - * More certs and chains can be added via AddCertificate and AddCertChain. - * - * An error results in a return value of NULL and an error set. - * - * XXXX CRLs - */ -NSSCMSSignedData * -NSS_CMSSignedData_CreateCertsOnly(NSSCMSMessage *cmsg, CERTCertificate *cert, PRBool include_chain) -{ - NSSCMSSignedData *sigd; - void *mark; - PLArenaPool *poolp; - SECStatus rv; - - if (!cmsg || !cert) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - - poolp = cmsg->poolp; - mark = PORT_ArenaMark(poolp); - - sigd = NSS_CMSSignedData_Create(cmsg); - if (sigd == NULL) - goto loser; - - /* no signerinfos, thus no digestAlgorithms */ - - /* but certs */ - if (include_chain) { - rv = NSS_CMSSignedData_AddCertChain(sigd, cert); - } else { - rv = NSS_CMSSignedData_AddCertificate(sigd, cert); - } - if (rv != SECSuccess) - goto loser; - - /* RFC2630 5.2 sez: - * In the degenerate case where there are no signers, the - * EncapsulatedContentInfo value being "signed" is irrelevant. In this - * case, the content type within the EncapsulatedContentInfo value being - * "signed" should be id-data (as defined in section 4), and the content - * field of the EncapsulatedContentInfo value should be omitted. - */ - rv = NSS_CMSContentInfo_SetContent_Data(cmsg, &(sigd->contentInfo), NULL, PR_TRUE); - if (rv != SECSuccess) - goto loser; - - PORT_ArenaUnmark(poolp, mark); - return sigd; - -loser: - if (sigd) - NSS_CMSSignedData_Destroy(sigd); - PORT_ArenaRelease(poolp, mark); - return NULL; -} - -/* TODO: - * NSS_CMSSignerInfo_GetReceiptRequest() - * NSS_CMSSignedData_HasReceiptRequest() - * easy way to iterate over signers - */ - diff --git a/security/nss/lib/smime/cmssiginfo.c b/security/nss/lib/smime/cmssiginfo.c deleted file mode 100644 index 675040b66..000000000 --- a/security/nss/lib/smime/cmssiginfo.c +++ /dev/null @@ -1,1037 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS signerInfo methods. - * - * $Id$ - */ - -#include "cmslocal.h" - -#include "cert.h" -#include "key.h" -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "pk11func.h" -#include "prtime.h" -#include "secerr.h" -#include "secder.h" -#include "cryptohi.h" - -#include "smime.h" - -/* ============================================================================= - * SIGNERINFO - */ -NSSCMSSignerInfo * -nss_cmssignerinfo_create(NSSCMSMessage *cmsg, NSSCMSSignerIDSelector type, - CERTCertificate *cert, SECItem *subjKeyID, SECKEYPublicKey *pubKey, - SECKEYPrivateKey *signingKey, SECOidTag digestalgtag); - -NSSCMSSignerInfo * -NSS_CMSSignerInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg, SECItem *subjKeyID, - SECKEYPublicKey *pubKey, SECKEYPrivateKey *signingKey, SECOidTag digestalgtag) -{ - return nss_cmssignerinfo_create(cmsg, NSSCMSSignerID_SubjectKeyID, NULL, subjKeyID, pubKey, signingKey, digestalgtag); -} - -NSSCMSSignerInfo * -NSS_CMSSignerInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert, SECOidTag digestalgtag) -{ - return nss_cmssignerinfo_create(cmsg, NSSCMSSignerID_IssuerSN, cert, NULL, NULL, NULL, digestalgtag); -} - -NSSCMSSignerInfo * -nss_cmssignerinfo_create(NSSCMSMessage *cmsg, NSSCMSSignerIDSelector type, - CERTCertificate *cert, SECItem *subjKeyID, SECKEYPublicKey *pubKey, - SECKEYPrivateKey *signingKey, SECOidTag digestalgtag) -{ - void *mark; - NSSCMSSignerInfo *signerinfo; - int version; - PLArenaPool *poolp; - - poolp = cmsg->poolp; - - mark = PORT_ArenaMark(poolp); - - signerinfo = (NSSCMSSignerInfo *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSSignerInfo)); - if (signerinfo == NULL) { - PORT_ArenaRelease(poolp, mark); - return NULL; - } - - - signerinfo->cmsg = cmsg; - - switch(type) { - case NSSCMSSignerID_IssuerSN: - signerinfo->signerIdentifier.identifierType = NSSCMSSignerID_IssuerSN; - if ((signerinfo->cert = CERT_DupCertificate(cert)) == NULL) - goto loser; - if ((signerinfo->signerIdentifier.id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert)) == NULL) - goto loser; - break; - case NSSCMSSignerID_SubjectKeyID: - signerinfo->signerIdentifier.identifierType = NSSCMSSignerID_SubjectKeyID; - PORT_Assert(subjKeyID); - if (!subjKeyID) - goto loser; - - signerinfo->signerIdentifier.id.subjectKeyID = PORT_ArenaNew(poolp, SECItem); - SECITEM_CopyItem(poolp, signerinfo->signerIdentifier.id.subjectKeyID, - subjKeyID); - signerinfo->signingKey = SECKEY_CopyPrivateKey(signingKey); - if (!signerinfo->signingKey) - goto loser; - signerinfo->pubKey = SECKEY_CopyPublicKey(pubKey); - if (!signerinfo->pubKey) - goto loser; - break; - default: - goto loser; - } - - /* set version right now */ - version = NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN; - /* RFC2630 5.3 "version is the syntax version number. If the .... " */ - if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID) - version = NSS_CMS_SIGNER_INFO_VERSION_SUBJKEY; - (void)SEC_ASN1EncodeInteger(poolp, &(signerinfo->version), (long)version); - - if (SECOID_SetAlgorithmID(poolp, &signerinfo->digestAlg, digestalgtag, NULL) != SECSuccess) - goto loser; - - PORT_ArenaUnmark(poolp, mark); - return signerinfo; - -loser: - PORT_ArenaRelease(poolp, mark); - return NULL; -} - -/* - * NSS_CMSSignerInfo_Destroy - destroy a SignerInfo data structure - */ -void -NSS_CMSSignerInfo_Destroy(NSSCMSSignerInfo *si) -{ - if (si->cert != NULL) - CERT_DestroyCertificate(si->cert); - - if (si->certList != NULL) - CERT_DestroyCertificateList(si->certList); - - /* XXX storage ??? */ -} - -/* - * NSS_CMSSignerInfo_Sign - sign something - * - */ -SECStatus -NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *contentType) -{ - CERTCertificate *cert; - SECKEYPrivateKey *privkey = NULL; - SECOidTag digestalgtag; - SECOidTag pubkAlgTag; - SECItem signature = { 0 }; - SECStatus rv; - PLArenaPool *poolp, *tmppoolp; - SECAlgorithmID *algID, freeAlgID; - CERTSubjectPublicKeyInfo *spki; - - PORT_Assert (digest != NULL); - - poolp = signerinfo->cmsg->poolp; - - switch (signerinfo->signerIdentifier.identifierType) { - case NSSCMSSignerID_IssuerSN: - cert = signerinfo->cert; - - if ((privkey = PK11_FindKeyByAnyCert(cert, signerinfo->cmsg->pwfn_arg)) == NULL) - goto loser; - algID = &cert->subjectPublicKeyInfo.algorithm; - break; - case NSSCMSSignerID_SubjectKeyID: - privkey = signerinfo->signingKey; - signerinfo->signingKey = NULL; - spki = SECKEY_CreateSubjectPublicKeyInfo(signerinfo->pubKey); - SECKEY_DestroyPublicKey(signerinfo->pubKey); - signerinfo->pubKey = NULL; - SECOID_CopyAlgorithmID(NULL, &freeAlgID, &spki->algorithm); - SECKEY_DestroySubjectPublicKeyInfo(spki); - algID = &freeAlgID; - break; - default: - goto loser; - } - digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo); - /* - * XXX I think there should be a cert-level interface for this, - * so that I do not have to know about subjectPublicKeyInfo... - */ - pubkAlgTag = SECOID_GetAlgorithmTag(algID); - if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID) { - SECOID_DestroyAlgorithmID(&freeAlgID, PR_FALSE); - } - - /* Fortezza MISSI have weird signature formats. - * Map them to standard DSA formats - */ - pubkAlgTag = PK11_FortezzaMapSig(pubkAlgTag); - - if (signerinfo->authAttr != NULL) { - SECOidTag signAlgTag; - SECItem encoded_attrs; - - /* find and fill in the message digest attribute. */ - rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr), - SEC_OID_PKCS9_MESSAGE_DIGEST, digest, PR_FALSE); - if (rv != SECSuccess) - goto loser; - - if (contentType != NULL) { - /* if the caller wants us to, find and fill in the content type attribute. */ - rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr), - SEC_OID_PKCS9_CONTENT_TYPE, contentType, PR_FALSE); - if (rv != SECSuccess) - goto loser; - } - - if ((tmppoolp = PORT_NewArena (1024)) == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* - * Before encoding, reorder the attributes so that when they - * are encoded, they will be conforming DER, which is required - * to have a specific order and that is what must be used for - * the hash/signature. We do this here, rather than building - * it into EncodeAttributes, because we do not want to do - * such reordering on incoming messages (which also uses - * EncodeAttributes) or our old signatures (and other "broken" - * implementations) will not verify. So, we want to guarantee - * that we send out good DER encodings of attributes, but not - * to expect to receive them. - */ - if (NSS_CMSAttributeArray_Reorder(signerinfo->authAttr) != SECSuccess) - goto loser; - - encoded_attrs.data = NULL; - encoded_attrs.len = 0; - if (NSS_CMSAttributeArray_Encode(tmppoolp, &(signerinfo->authAttr), - &encoded_attrs) == NULL) - goto loser; - - signAlgTag = NSS_CMSUtil_MakeSignatureAlgorithm(digestalgtag, pubkAlgTag); - rv = SEC_SignData(&signature, encoded_attrs.data, encoded_attrs.len, - privkey, signAlgTag); - PORT_FreeArena(tmppoolp, PR_FALSE); /* awkward memory management :-( */ - } else { - rv = SGN_Digest(privkey, digestalgtag, &signature, digest); - } - SECKEY_DestroyPrivateKey(privkey); - privkey = NULL; - - if (rv != SECSuccess) - goto loser; - - if (SECITEM_CopyItem(poolp, &(signerinfo->encDigest), &signature) - != SECSuccess) - goto loser; - - SECITEM_FreeItem(&signature, PR_FALSE); - - if (SECOID_SetAlgorithmID(poolp, &(signerinfo->digestEncAlg), pubkAlgTag, - NULL) != SECSuccess) - goto loser; - - return SECSuccess; - -loser: - if (signature.len != 0) - SECITEM_FreeItem (&signature, PR_FALSE); - if (privkey) - SECKEY_DestroyPrivateKey(privkey); - return SECFailure; -} - -SECStatus -NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb, - SECCertUsage certusage) -{ - CERTCertificate *cert; - int64 stime; - - if ((cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb)) == NULL) { - signerinfo->verificationStatus = NSSCMSVS_SigningCertNotFound; - return SECFailure; - } - - /* - * Get and convert the signing time; if available, it will be used - * both on the cert verification and for importing the sender - * email profile. - */ - if (NSS_CMSSignerInfo_GetSigningTime (signerinfo, &stime) != SECSuccess) - stime = PR_Now(); /* not found or conversion failed, so check against now */ - - /* - * XXX This uses the signing time, if available. Additionally, we - * might want to, if there is no signing time, get the message time - * from the mail header itself, and use that. That would require - * a change to our interface though, and for S/MIME callers to pass - * in a time (and for non-S/MIME callers to pass in nothing, or - * maybe make them pass in the current time, always?). - */ - if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, stime, - signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) { - signerinfo->verificationStatus = NSSCMSVS_SigningCertNotTrusted; - return SECFailure; - } - return SECSuccess; -} - -/* - * NSS_CMSSignerInfo_Verify - verify the signature of a single SignerInfo - * - * Just verifies the signature. The assumption is that verification of - * the certificate is done already. - */ -SECStatus -NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, - SECItem *digest, /* may be NULL */ - SECItem *contentType) /* may be NULL */ -{ - SECKEYPublicKey *publickey = NULL; - NSSCMSAttribute *attr; - SECItem encoded_attrs; - CERTCertificate *cert; - NSSCMSVerificationStatus vs = NSSCMSVS_Unverified; - PLArenaPool *poolp; - SECOidTag digestalgtag; - SECOidTag pubkAlgTag; - SECOidTag signAlgTag; - - if (signerinfo == NULL) - return SECFailure; - - /* NSS_CMSSignerInfo_GetSigningCertificate will fail if 2nd parm is NULL - ** and cert has not been verified - */ - cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, NULL); - if (cert == NULL) { - vs = NSSCMSVS_SigningCertNotFound; - goto loser; - } - - if ((publickey = CERT_ExtractPublicKey(cert)) == NULL) { - vs = NSSCMSVS_ProcessingError; - goto loser; - } - - digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo); - - /* - * XXX This may not be the right set of algorithms to check. - * I'd prefer to trust that just calling VFY_Verify{Data,Digest} - * would do the right thing (and set an error if it could not); - * then additional algorithms could be handled by that code - * and we would Just Work. So this check should just be removed, - * but not until the VFY code is better at setting errors. - */ - pubkAlgTag = SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg)); - switch (pubkAlgTag) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - case SEC_OID_ANSIX9_DSA_SIGNATURE: - case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: - case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: - case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: - case SEC_OID_ANSIX962_EC_PUBLIC_KEY: - /* ok */ - break; - case SEC_OID_UNKNOWN: - vs = NSSCMSVS_SignatureAlgorithmUnknown; - goto loser; - default: - vs = NSSCMSVS_SignatureAlgorithmUnsupported; - goto loser; - } - - signAlgTag = NSS_CMSUtil_MakeSignatureAlgorithm(digestalgtag, pubkAlgTag); - - if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) { - if (contentType) { - /* - * Check content type - * - * RFC2630 sez that if there are any authenticated attributes, - * then there must be one for content type which matches the - * content type of the content being signed, and there must - * be one for message digest which matches our message digest. - * So check these things first. - */ - attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr, - SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE); - if (attr == NULL) { - vs = NSSCMSVS_MalformedSignature; - goto loser; - } - - if (NSS_CMSAttribute_CompareValue(attr, contentType) == PR_FALSE) { - vs = NSSCMSVS_MalformedSignature; - goto loser; - } - } - - /* - * Check digest - */ - attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr, - SEC_OID_PKCS9_MESSAGE_DIGEST, PR_TRUE); - if (attr == NULL) { - vs = NSSCMSVS_MalformedSignature; - goto loser; - } - if (!digest || - NSS_CMSAttribute_CompareValue(attr, digest) == PR_FALSE) { - vs = NSSCMSVS_DigestMismatch; - goto loser; - } - - if ((poolp = PORT_NewArena (1024)) == NULL) { - vs = NSSCMSVS_ProcessingError; - goto loser; - } - - /* - * Check signature - * - * The signature is based on a digest of the DER-encoded authenticated - * attributes. So, first we encode and then we digest/verify. - * we trust the decoder to have the attributes in the right (sorted) - * order - */ - encoded_attrs.data = NULL; - encoded_attrs.len = 0; - - if (NSS_CMSAttributeArray_Encode(poolp, &(signerinfo->authAttr), - &encoded_attrs) == NULL || - encoded_attrs.data == NULL || encoded_attrs.len == 0) { - vs = NSSCMSVS_ProcessingError; - goto loser; - } - - vs = (VFY_VerifyData (encoded_attrs.data, encoded_attrs.len, - publickey, &(signerinfo->encDigest), signAlgTag, - signerinfo->cmsg->pwfn_arg) != SECSuccess) - ? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature; - - PORT_FreeArena(poolp, PR_FALSE); /* awkward memory management :-( */ - - } else { - SECItem *sig; - - /* No authenticated attributes. - ** The signature is based on the plain message digest. - */ - sig = &(signerinfo->encDigest); - if (sig->len == 0) - goto loser; - - vs = (!digest || - VFY_VerifyDigest(digest, publickey, sig, signAlgTag, - signerinfo->cmsg->pwfn_arg) != SECSuccess) - ? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature; - } - - if (vs == NSSCMSVS_BadSignature) { - /* - * XXX Change the generic error into our specific one, because - * in that case we get a better explanation out of the Security - * Advisor. This is really a bug in our error strings (the - * "generic" error has a lousy/wrong message associated with it - * which assumes the signature verification was done for the - * purposes of checking the issuer signature on a certificate) - * but this is at least an easy workaround and/or in the - * Security Advisor, which specifically checks for the error - * SEC_ERROR_PKCS7_BAD_SIGNATURE and gives more explanation - * in that case but does not similarly check for - * SEC_ERROR_BAD_SIGNATURE. It probably should, but then would - * probably say the wrong thing in the case that it *was* the - * certificate signature check that failed during the cert - * verification done above. Our error handling is really a mess. - */ - if (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE) - PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); - } - - if (publickey != NULL) - SECKEY_DestroyPublicKey (publickey); - - signerinfo->verificationStatus = vs; - - return (vs == NSSCMSVS_GoodSignature) ? SECSuccess : SECFailure; - -loser: - if (publickey != NULL) - SECKEY_DestroyPublicKey (publickey); - - signerinfo->verificationStatus = vs; - - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - return SECFailure; -} - -NSSCMSVerificationStatus -NSS_CMSSignerInfo_GetVerificationStatus(NSSCMSSignerInfo *signerinfo) -{ - return signerinfo->verificationStatus; -} - -SECOidData * -NSS_CMSSignerInfo_GetDigestAlg(NSSCMSSignerInfo *signerinfo) -{ - return SECOID_FindOID (&(signerinfo->digestAlg.algorithm)); -} - -SECOidTag -NSS_CMSSignerInfo_GetDigestAlgTag(NSSCMSSignerInfo *signerinfo) -{ - SECOidData *algdata; - - if (!signerinfo) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SEC_OID_UNKNOWN; - } - - algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm)); - if (algdata != NULL) - return algdata->offset; - else - return SEC_OID_UNKNOWN; -} - -CERTCertificateList * -NSS_CMSSignerInfo_GetCertList(NSSCMSSignerInfo *signerinfo) -{ - return signerinfo->certList; -} - -int -NSS_CMSSignerInfo_GetVersion(NSSCMSSignerInfo *signerinfo) -{ - unsigned long version; - - /* always take apart the SECItem */ - if (SEC_ASN1DecodeInteger(&(signerinfo->version), &version) != SECSuccess) - return 0; - else - return (int)version; -} - -/* - * NSS_CMSSignerInfo_GetSigningTime - return the signing time, - * in UTCTime or GeneralizedTime format, - * of a CMS signerInfo. - * - * sinfo - signerInfo data for this signer - * - * Returns a pointer to XXXX (what?) - * A return value of NULL is an error. - */ -SECStatus -NSS_CMSSignerInfo_GetSigningTime(NSSCMSSignerInfo *sinfo, PRTime *stime) -{ - NSSCMSAttribute *attr; - SECItem *value; - - if (sinfo == NULL) - return SECFailure; - - if (sinfo->signingTime != 0) { - *stime = sinfo->signingTime; /* cached copy */ - return SECSuccess; - } - - attr = NSS_CMSAttributeArray_FindAttrByOidTag(sinfo->authAttr, SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE); - /* XXXX multi-valued attributes NIH */ - if (attr == NULL || (value = NSS_CMSAttribute_GetValue(attr)) == NULL) - return SECFailure; - if (DER_DecodeTimeChoice(stime, value) != SECSuccess) - return SECFailure; - sinfo->signingTime = *stime; /* make cached copy */ - return SECSuccess; -} - -/* - * Return the signing cert of a CMS signerInfo. - * - * the certs in the enclosing SignedData must have been imported already - */ -CERTCertificate * -NSS_CMSSignerInfo_GetSigningCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb) -{ - CERTCertificate *cert; - NSSCMSSignerIdentifier *sid; - - if (signerinfo->cert != NULL) - return signerinfo->cert; - - /* no certdb, and cert hasn't been set yet? */ - if (certdb == NULL) - return NULL; - - /* - * This cert will also need to be freed, but since we save it - * in signerinfo for later, we do not want to destroy it when - * we leave this function -- we let the clean-up of the entire - * cinfo structure later do the destroy of this cert. - */ - sid = &signerinfo->signerIdentifier; - switch (sid->identifierType) { - case NSSCMSSignerID_IssuerSN: - cert = CERT_FindCertByIssuerAndSN(certdb, sid->id.issuerAndSN); - break; - case NSSCMSSignerID_SubjectKeyID: - cert = CERT_FindCertBySubjectKeyID(certdb, sid->id.subjectKeyID); - break; - default: - cert = NULL; - break; - } - - /* cert can be NULL at that point */ - signerinfo->cert = cert; /* earmark it */ - - return cert; -} - -/* - * NSS_CMSSignerInfo_GetSignerCommonName - return the common name of the signer - * - * sinfo - signerInfo data for this signer - * - * Returns a pointer to allocated memory, which must be freed with PORT_Free. - * A return value of NULL is an error. - */ -char * -NSS_CMSSignerInfo_GetSignerCommonName(NSSCMSSignerInfo *sinfo) -{ - CERTCertificate *signercert; - - /* will fail if cert is not verified */ - if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL) - return NULL; - - return (CERT_GetCommonName(&signercert->subject)); -} - -/* - * NSS_CMSSignerInfo_GetSignerEmailAddress - return the common name of the signer - * - * sinfo - signerInfo data for this signer - * - * Returns a pointer to allocated memory, which must be freed. - * A return value of NULL is an error. - */ -char * -NSS_CMSSignerInfo_GetSignerEmailAddress(NSSCMSSignerInfo *sinfo) -{ - CERTCertificate *signercert; - - if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL) - return NULL; - - if (!signercert->emailAddr || !signercert->emailAddr[0]) - return NULL; - - return (PORT_Strdup(signercert->emailAddr)); -} - -/* - * NSS_CMSSignerInfo_AddAuthAttr - add an attribute to the - * authenticated (i.e. signed) attributes of "signerinfo". - */ -SECStatus -NSS_CMSSignerInfo_AddAuthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr) -{ - return NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->authAttr), attr); -} - -/* - * NSS_CMSSignerInfo_AddUnauthAttr - add an attribute to the - * unauthenticated attributes of "signerinfo". - */ -SECStatus -NSS_CMSSignerInfo_AddUnauthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr) -{ - return NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->unAuthAttr), attr); -} - -/* - * NSS_CMSSignerInfo_AddSigningTime - add the signing time to the - * authenticated (i.e. signed) attributes of "signerinfo". - * - * This is expected to be included in outgoing signed - * messages for email (S/MIME) but is likely useful in other situations. - * - * This should only be added once; a second call will do nothing. - * - * XXX This will probably just shove the current time into "signerinfo" - * but it will not actually get signed until the entire item is - * processed for encoding. Is this (expected to be small) delay okay? - */ -SECStatus -NSS_CMSSignerInfo_AddSigningTime(NSSCMSSignerInfo *signerinfo, PRTime t) -{ - NSSCMSAttribute *attr; - SECItem stime; - void *mark; - PLArenaPool *poolp; - - poolp = signerinfo->cmsg->poolp; - - mark = PORT_ArenaMark(poolp); - - /* create new signing time attribute */ - if (DER_EncodeTimeChoice(NULL, &stime, t) != SECSuccess) - goto loser; - - if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SIGNING_TIME, &stime, PR_FALSE)) == NULL) { - SECITEM_FreeItem (&stime, PR_FALSE); - goto loser; - } - - SECITEM_FreeItem (&stime, PR_FALSE); - - if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess) - goto loser; - - PORT_ArenaUnmark (poolp, mark); - - return SECSuccess; - -loser: - PORT_ArenaRelease (poolp, mark); - return SECFailure; -} - -/* - * NSS_CMSSignerInfo_AddSMIMECaps - add a SMIMECapabilities attribute to the - * authenticated (i.e. signed) attributes of "signerinfo". - * - * This is expected to be included in outgoing signed - * messages for email (S/MIME). - */ -SECStatus -NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo) -{ - NSSCMSAttribute *attr; - SECItem *smimecaps = NULL; - void *mark; - PLArenaPool *poolp; - - poolp = signerinfo->cmsg->poolp; - - mark = PORT_ArenaMark(poolp); - - smimecaps = SECITEM_AllocItem(poolp, NULL, 0); - if (smimecaps == NULL) - goto loser; - - /* create new signing time attribute */ - if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps, - PK11_FortezzaHasKEA(signerinfo->cert)) != SECSuccess) - goto loser; - - if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SMIME_CAPABILITIES, smimecaps, PR_TRUE)) == NULL) - goto loser; - - if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess) - goto loser; - - PORT_ArenaUnmark (poolp, mark); - return SECSuccess; - -loser: - PORT_ArenaRelease (poolp, mark); - return SECFailure; -} - -/* - * NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the - * authenticated (i.e. signed) attributes of "signerinfo". - * - * This is expected to be included in outgoing signed messages for email (S/MIME). - */ -SECStatus -NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb) -{ - NSSCMSAttribute *attr; - SECItem *smimeekp = NULL; - void *mark; - PLArenaPool *poolp; - - /* verify this cert for encryption */ - if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) { - return SECFailure; - } - - poolp = signerinfo->cmsg->poolp; - mark = PORT_ArenaMark(poolp); - - smimeekp = SECITEM_AllocItem(poolp, NULL, 0); - if (smimeekp == NULL) - goto loser; - - /* create new signing time attribute */ - if (NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess) - goto loser; - - if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL) - goto loser; - - if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess) - goto loser; - - PORT_ArenaUnmark (poolp, mark); - return SECSuccess; - -loser: - PORT_ArenaRelease (poolp, mark); - return SECFailure; -} - -/* - * NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the - * authenticated (i.e. signed) attributes of "signerinfo", using the OID prefered by Microsoft. - * - * This is expected to be included in outgoing signed messages for email (S/MIME), - * if compatibility with Microsoft mail clients is wanted. - */ -SECStatus -NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb) -{ - NSSCMSAttribute *attr; - SECItem *smimeekp = NULL; - void *mark; - PLArenaPool *poolp; - - /* verify this cert for encryption */ - if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) { - return SECFailure; - } - - poolp = signerinfo->cmsg->poolp; - mark = PORT_ArenaMark(poolp); - - smimeekp = SECITEM_AllocItem(poolp, NULL, 0); - if (smimeekp == NULL) - goto loser; - - /* create new signing time attribute */ - if (NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess) - goto loser; - - if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL) - goto loser; - - if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess) - goto loser; - - PORT_ArenaUnmark (poolp, mark); - return SECSuccess; - -loser: - PORT_ArenaRelease (poolp, mark); - return SECFailure; -} - -/* - * NSS_CMSSignerInfo_AddCounterSignature - countersign a signerinfo - * - * 1. digest the DER-encoded signature value of the original signerinfo - * 2. create new signerinfo with correct version, sid, digestAlg - * 3. add message-digest authAttr, but NO content-type - * 4. sign the authAttrs - * 5. DER-encode the new signerInfo - * 6. add the whole thing to original signerInfo's unAuthAttrs - * as a SEC_OID_PKCS9_COUNTER_SIGNATURE attribute - * - * XXXX give back the new signerinfo? - */ -SECStatus -NSS_CMSSignerInfo_AddCounterSignature(NSSCMSSignerInfo *signerinfo, - SECOidTag digestalg, CERTCertificate signingcert) -{ - /* XXXX TBD XXXX */ - return SECFailure; -} - -/* - * XXXX the following needs to be done in the S/MIME layer code - * after signature of a signerinfo is verified - */ -SECStatus -NSS_SMIMESignerInfo_SaveSMIMEProfile(NSSCMSSignerInfo *signerinfo) -{ - CERTCertificate *cert = NULL; - SECItem *profile = NULL; - NSSCMSAttribute *attr; - SECItem *stime = NULL; - SECItem *ekp; - CERTCertDBHandle *certdb; - int save_error; - SECStatus rv; - PRBool must_free_cert = PR_FALSE; - - certdb = CERT_GetDefaultCertDB(); - - /* sanity check - see if verification status is ok (unverified does not count...) */ - if (signerinfo->verificationStatus != NSSCMSVS_GoodSignature) - return SECFailure; - - /* find preferred encryption cert */ - if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr) && - (attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr, - SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, PR_TRUE)) != NULL) - { /* we have a SMIME_ENCRYPTION_KEY_PREFERENCE attribute! */ - ekp = NSS_CMSAttribute_GetValue(attr); - if (ekp == NULL) - return SECFailure; - - /* we assume that all certs coming with the message have been imported to the */ - /* temporary database */ - cert = NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(certdb, ekp); - if (cert == NULL) - return SECFailure; - must_free_cert = PR_TRUE; - } - - if (cert == NULL) { - /* no preferred cert found? - * find the cert the signerinfo is signed with instead */ - cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb); - if (cert == NULL || cert->emailAddr == NULL || !cert->emailAddr[0]) - return SECFailure; - } - - /* verify this cert for encryption (has been verified for signing so far) */ - /* don't verify this cert for encryption. It may just be a signing cert. - * that's OK, we can still save the S/MIME profile. The encryption cert - * should have already been saved */ -#ifdef notdef - if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) { - if (must_free_cert) - CERT_DestroyCertificate(cert); - return SECFailure; - } -#endif - - /* XXX store encryption cert permanently? */ - - /* - * Remember the current error set because we do not care about - * anything set by the functions we are about to call. - */ - save_error = PORT_GetError(); - - if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) { - attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr, - SEC_OID_PKCS9_SMIME_CAPABILITIES, - PR_TRUE); - profile = NSS_CMSAttribute_GetValue(attr); - attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr, - SEC_OID_PKCS9_SIGNING_TIME, - PR_TRUE); - stime = NSS_CMSAttribute_GetValue(attr); - } - - rv = CERT_SaveSMimeProfile (cert, profile, stime); - if (must_free_cert) - CERT_DestroyCertificate(cert); - - /* - * Restore the saved error in case the calls above set a new - * one that we do not actually care about. - */ - PORT_SetError (save_error); - - return rv; -} - -/* - * NSS_CMSSignerInfo_IncludeCerts - set cert chain inclusion mode for this signer - */ -SECStatus -NSS_CMSSignerInfo_IncludeCerts(NSSCMSSignerInfo *signerinfo, NSSCMSCertChainMode cm, SECCertUsage usage) -{ - if (signerinfo->cert == NULL) - return SECFailure; - - /* don't leak if we get called twice */ - if (signerinfo->certList != NULL) { - CERT_DestroyCertificateList(signerinfo->certList); - signerinfo->certList = NULL; - } - - switch (cm) { - case NSSCMSCM_None: - signerinfo->certList = NULL; - break; - case NSSCMSCM_CertOnly: - signerinfo->certList = CERT_CertListFromCert(signerinfo->cert); - break; - case NSSCMSCM_CertChain: - signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_FALSE); - break; - case NSSCMSCM_CertChainWithRoot: - signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE); - break; - } - - if (cm != NSSCMSCM_None && signerinfo->certList == NULL) - return SECFailure; - - return SECSuccess; -} diff --git a/security/nss/lib/smime/cmst.h b/security/nss/lib/smime/cmst.h deleted file mode 100644 index 82f24da14..000000000 --- a/security/nss/lib/smime/cmst.h +++ /dev/null @@ -1,534 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * Header for CMS types. - * - * $Id$ - */ - -#ifndef _CMST_H_ -#define _CMST_H_ - -#include "seccomon.h" -#include "secoidt.h" -#include "certt.h" -#include "secmodt.h" -#include "secmodt.h" - -#include "plarena.h" - -/* Non-opaque objects. NOTE, though: I want them to be treated as - * opaque as much as possible. If I could hide them completely, - * I would. (I tried, but ran into trouble that was taking me too - * much time to get out of.) I still intend to try to do so. - * In fact, the only type that "outsiders" should even *name* is - * NSSCMSMessage, and they should not reference its fields. - */ -/* rjr: PKCS #11 cert handling (pk11cert.c) does use NSSCMSRecipientInfo's. - * This is because when we search the recipient list for the cert and key we - * want, we need to invert the order of the loops we used to have. The old - * loops were: - * - * For each recipient { - * find_cert = PK11_Find_AllCert(recipient->issuerSN); - * [which unrolls to... ] - * For each slot { - * Log into slot; - * search slot for cert; - * } - * } - * - * the new loop searchs all the recipients at once on a slot. this allows - * PKCS #11 to order slots in such a way that logout slots don't get checked - * if we can find the cert on a logged in slot. This eliminates lots of - * spurious password prompts when smart cards are installed... so why this - * comment? If you make NSSCMSRecipientInfo completely opaque, you need - * to provide a non-opaque list of issuerSN's (the only field PKCS#11 needs - * and fix up pk11cert.c first. NOTE: Only S/MIME calls this special PKCS #11 - * function. - */ - -typedef struct NSSCMSMessageStr NSSCMSMessage; - -typedef union NSSCMSContentUnion NSSCMSContent; -typedef struct NSSCMSContentInfoStr NSSCMSContentInfo; - -typedef struct NSSCMSSignedDataStr NSSCMSSignedData; -typedef struct NSSCMSSignerInfoStr NSSCMSSignerInfo; -typedef struct NSSCMSSignerIdentifierStr NSSCMSSignerIdentifier; - -typedef struct NSSCMSEnvelopedDataStr NSSCMSEnvelopedData; -typedef struct NSSCMSOriginatorInfoStr NSSCMSOriginatorInfo; -typedef struct NSSCMSRecipientInfoStr NSSCMSRecipientInfo; - -typedef struct NSSCMSDigestedDataStr NSSCMSDigestedData; -typedef struct NSSCMSEncryptedDataStr NSSCMSEncryptedData; - -typedef struct NSSCMSSMIMEKEAParametersStr NSSCMSSMIMEKEAParameters; - -typedef struct NSSCMSAttributeStr NSSCMSAttribute; - -typedef struct NSSCMSDecoderContextStr NSSCMSDecoderContext; -typedef struct NSSCMSEncoderContextStr NSSCMSEncoderContext; - -typedef struct NSSCMSCipherContextStr NSSCMSCipherContext; -typedef struct NSSCMSDigestContextStr NSSCMSDigestContext; - -/* - * Type of function passed to NSSCMSDecode or NSSCMSDecoderStart. - * If specified, this is where the content bytes (only) will be "sent" - * as they are recovered during the decoding. - * And: - * Type of function passed to NSSCMSEncode or NSSCMSEncoderStart. - * This is where the DER-encoded bytes will be "sent". - * - * XXX Should just combine this with NSSCMSEncoderContentCallback type - * and use a simpler, common name. - */ -typedef void (*NSSCMSContentCallback)(void *arg, const char *buf, unsigned long len); - -/* - * Type of function passed to NSSCMSDecode or NSSCMSDecoderStart - * to retrieve the decryption key. This function is intended to be - * used for EncryptedData content info's which do not have a key available - * in a certificate, etc. - */ -typedef PK11SymKey *(*NSSCMSGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid); - - -/* ============================================================================= - * ENCAPSULATED CONTENTINFO & CONTENTINFO - */ - -union NSSCMSContentUnion { - /* either unstructured */ - SECItem * data; - /* or structured data */ - NSSCMSDigestedData * digestedData; - NSSCMSEncryptedData * encryptedData; - NSSCMSEnvelopedData * envelopedData; - NSSCMSSignedData * signedData; - /* or anonymous pointer to something */ - void * pointer; -}; - -struct NSSCMSContentInfoStr { - SECItem contentType; - NSSCMSContent content; - /* --------- local; not part of encoding --------- */ - SECOidData * contentTypeTag; - - /* additional info for encryptedData and envelopedData */ - /* we waste this space for signedData and digestedData. sue me. */ - - SECAlgorithmID contentEncAlg; - SECItem * rawContent; /* encrypted DER, optional */ - /* XXXX bytes not encrypted, but encoded? */ - /* --------- local; not part of encoding --------- */ - PK11SymKey * bulkkey; /* bulk encryption key */ - int keysize; /* size of bulk encryption key - * (only used by creation code) */ - SECOidTag contentEncAlgTag; /* oid tag of encryption algorithm - * (only used by creation code) */ - NSSCMSCipherContext *ciphcx; /* context for en/decryption going on */ - NSSCMSDigestContext *digcx; /* context for digesting going on */ -}; - -/* ============================================================================= - * MESSAGE - */ - -struct NSSCMSMessageStr { - NSSCMSContentInfo contentInfo; /* "outer" cinfo */ - /* --------- local; not part of encoding --------- */ - PLArenaPool * poolp; - PRBool poolp_is_ours; - int refCount; - /* properties of the "inner" data */ - SECAlgorithmID ** detached_digestalgs; - SECItem ** detached_digests; - void * pwfn_arg; - NSSCMSGetDecryptKeyCallback decrypt_key_cb; - void * decrypt_key_cb_arg; -}; - -/* ============================================================================= - * SIGNEDDATA - */ - -struct NSSCMSSignedDataStr { - SECItem version; - SECAlgorithmID ** digestAlgorithms; - NSSCMSContentInfo contentInfo; - SECItem ** rawCerts; - CERTSignedCrl ** crls; - NSSCMSSignerInfo ** signerInfos; - /* --------- local; not part of encoding --------- */ - NSSCMSMessage * cmsg; /* back pointer to message */ - SECItem ** digests; - CERTCertificate ** certs; - CERTCertificateList ** certLists; - CERTCertificate ** tempCerts; /* temporary certs, needed - * for example for signature - * verification */ -}; -#define NSS_CMS_SIGNED_DATA_VERSION_BASIC 1 /* what we *create* */ -#define NSS_CMS_SIGNED_DATA_VERSION_EXT 3 /* what we *create* */ - -typedef enum { - NSSCMSVS_Unverified = 0, - NSSCMSVS_GoodSignature = 1, - NSSCMSVS_BadSignature = 2, - NSSCMSVS_DigestMismatch = 3, - NSSCMSVS_SigningCertNotFound = 4, - NSSCMSVS_SigningCertNotTrusted = 5, - NSSCMSVS_SignatureAlgorithmUnknown = 6, - NSSCMSVS_SignatureAlgorithmUnsupported = 7, - NSSCMSVS_MalformedSignature = 8, - NSSCMSVS_ProcessingError = 9 -} NSSCMSVerificationStatus; - -typedef enum { - NSSCMSSignerID_IssuerSN = 0, - NSSCMSSignerID_SubjectKeyID = 1 -} NSSCMSSignerIDSelector; - -struct NSSCMSSignerIdentifierStr { - NSSCMSSignerIDSelector identifierType; - union { - CERTIssuerAndSN *issuerAndSN; - SECItem *subjectKeyID; - } id; -}; - -struct NSSCMSSignerInfoStr { - SECItem version; - NSSCMSSignerIdentifier signerIdentifier; - SECAlgorithmID digestAlg; - NSSCMSAttribute ** authAttr; - SECAlgorithmID digestEncAlg; - SECItem encDigest; - NSSCMSAttribute ** unAuthAttr; - /* --------- local; not part of encoding --------- */ - NSSCMSMessage * cmsg; /* back pointer to message */ - CERTCertificate * cert; - CERTCertificateList * certList; - PRTime signingTime; - NSSCMSVerificationStatus verificationStatus; - SECKEYPrivateKey * signingKey; /* Used if we're using subjKeyID*/ - SECKEYPublicKey * pubKey; -}; -#define NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */ -#define NSS_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */ - -typedef enum { - NSSCMSCM_None = 0, - NSSCMSCM_CertOnly = 1, - NSSCMSCM_CertChain = 2, - NSSCMSCM_CertChainWithRoot = 3 -} NSSCMSCertChainMode; - -/* ============================================================================= - * ENVELOPED DATA - */ -struct NSSCMSEnvelopedDataStr { - SECItem version; - NSSCMSOriginatorInfo * originatorInfo; /* optional */ - NSSCMSRecipientInfo ** recipientInfos; - NSSCMSContentInfo contentInfo; - NSSCMSAttribute ** unprotectedAttr; - /* --------- local; not part of encoding --------- */ - NSSCMSMessage * cmsg; /* back pointer to message */ -}; -#define NSS_CMS_ENVELOPED_DATA_VERSION_REG 0 /* what we *create* */ -#define NSS_CMS_ENVELOPED_DATA_VERSION_ADV 2 /* what we *create* */ - -struct NSSCMSOriginatorInfoStr { - SECItem ** rawCerts; - CERTSignedCrl ** crls; - /* --------- local; not part of encoding --------- */ - CERTCertificate ** certs; -}; - -/* ----------------------------------------------------------------------------- - * key transport recipient info - */ -typedef enum { - NSSCMSRecipientID_IssuerSN = 0, - NSSCMSRecipientID_SubjectKeyID = 1, - NSSCMSRecipientID_BrandNew = 2 -} NSSCMSRecipientIDSelector; - -struct NSSCMSRecipientIdentifierStr { - NSSCMSRecipientIDSelector identifierType; - union { - CERTIssuerAndSN *issuerAndSN; - SECItem *subjectKeyID; - } id; -}; -typedef struct NSSCMSRecipientIdentifierStr NSSCMSRecipientIdentifier; - -struct NSSCMSKeyTransRecipientInfoStr { - SECItem version; - NSSCMSRecipientIdentifier recipientIdentifier; - SECAlgorithmID keyEncAlg; - SECItem encKey; -}; -typedef struct NSSCMSKeyTransRecipientInfoStr NSSCMSKeyTransRecipientInfo; - -/* - * View comments before NSSCMSRecipientInfoStr for purpose of this - * structure. - */ -struct NSSCMSKeyTransRecipientInfoExStr { - NSSCMSKeyTransRecipientInfo recipientInfo; - int version; /* version of this structure (0) */ - SECKEYPublicKey *pubKey; -}; - -typedef struct NSSCMSKeyTransRecipientInfoExStr NSSCMSKeyTransRecipientInfoEx; - -#define NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_ISSUERSN 0 /* what we *create* */ -#define NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_SUBJKEY 2 /* what we *create* */ - -/* ----------------------------------------------------------------------------- - * key agreement recipient info - */ -struct NSSCMSOriginatorPublicKeyStr { - SECAlgorithmID algorithmIdentifier; - SECItem publicKey; /* bit string! */ -}; -typedef struct NSSCMSOriginatorPublicKeyStr NSSCMSOriginatorPublicKey; - -typedef enum { - NSSCMSOriginatorIDOrKey_IssuerSN = 0, - NSSCMSOriginatorIDOrKey_SubjectKeyID = 1, - NSSCMSOriginatorIDOrKey_OriginatorPublicKey = 2 -} NSSCMSOriginatorIDOrKeySelector; - -struct NSSCMSOriginatorIdentifierOrKeyStr { - NSSCMSOriginatorIDOrKeySelector identifierType; - union { - CERTIssuerAndSN *issuerAndSN; /* static-static */ - SECItem *subjectKeyID; /* static-static */ - NSSCMSOriginatorPublicKey originatorPublicKey; /* ephemeral-static */ - } id; -}; -typedef struct NSSCMSOriginatorIdentifierOrKeyStr NSSCMSOriginatorIdentifierOrKey; - -struct NSSCMSRecipientKeyIdentifierStr { - SECItem * subjectKeyIdentifier; - SECItem * date; /* optional */ - SECItem * other; /* optional */ -}; -typedef struct NSSCMSRecipientKeyIdentifierStr NSSCMSRecipientKeyIdentifier; - -typedef enum { - NSSCMSKeyAgreeRecipientID_IssuerSN = 0, - NSSCMSKeyAgreeRecipientID_RKeyID = 1 -} NSSCMSKeyAgreeRecipientIDSelector; - -struct NSSCMSKeyAgreeRecipientIdentifierStr { - NSSCMSKeyAgreeRecipientIDSelector identifierType; - union { - CERTIssuerAndSN *issuerAndSN; - NSSCMSRecipientKeyIdentifier recipientKeyIdentifier; - } id; -}; -typedef struct NSSCMSKeyAgreeRecipientIdentifierStr NSSCMSKeyAgreeRecipientIdentifier; - -struct NSSCMSRecipientEncryptedKeyStr { - NSSCMSKeyAgreeRecipientIdentifier recipientIdentifier; - SECItem encKey; -}; -typedef struct NSSCMSRecipientEncryptedKeyStr NSSCMSRecipientEncryptedKey; - -struct NSSCMSKeyAgreeRecipientInfoStr { - SECItem version; - NSSCMSOriginatorIdentifierOrKey originatorIdentifierOrKey; - SECItem * ukm; /* optional */ - SECAlgorithmID keyEncAlg; - NSSCMSRecipientEncryptedKey ** recipientEncryptedKeys; -}; -typedef struct NSSCMSKeyAgreeRecipientInfoStr NSSCMSKeyAgreeRecipientInfo; - -#define NSS_CMS_KEYAGREE_RECIPIENT_INFO_VERSION 3 /* what we *create* */ - -/* ----------------------------------------------------------------------------- - * KEK recipient info - */ -struct NSSCMSKEKIdentifierStr { - SECItem keyIdentifier; - SECItem * date; /* optional */ - SECItem * other; /* optional */ -}; -typedef struct NSSCMSKEKIdentifierStr NSSCMSKEKIdentifier; - -struct NSSCMSKEKRecipientInfoStr { - SECItem version; - NSSCMSKEKIdentifier kekIdentifier; - SECAlgorithmID keyEncAlg; - SECItem encKey; -}; -typedef struct NSSCMSKEKRecipientInfoStr NSSCMSKEKRecipientInfo; - -#define NSS_CMS_KEK_RECIPIENT_INFO_VERSION 4 /* what we *create* */ - -/* ----------------------------------------------------------------------------- - * recipient info - */ - -typedef enum { - NSSCMSRecipientInfoID_KeyTrans = 0, - NSSCMSRecipientInfoID_KeyAgree = 1, - NSSCMSRecipientInfoID_KEK = 2 -} NSSCMSRecipientInfoIDSelector; - -/* - * In order to preserve backwards binary compatibility when implementing - * creation of Recipient Info's that uses subjectKeyID in the - * keyTransRecipientInfo we need to stash a public key pointer in this - * structure somewhere. We figured out that NSSCMSKeyTransRecipientInfo - * is the smallest member of the ri union. We're in luck since that's - * the very structure that would need to use the public key. So we created - * a new structure NSSCMSKeyTransRecipientInfoEx which has a member - * NSSCMSKeyTransRecipientInfo as the first member followed by a version - * and a public key pointer. This way we can keep backwards compatibility - * without changing the size of this structure. - * - * BTW, size of structure: - * NSSCMSKeyTransRecipientInfo: 9 ints, 4 pointers - * NSSCMSKeyAgreeRecipientInfo: 12 ints, 8 pointers - * NSSCMSKEKRecipientInfo: 10 ints, 7 pointers - * - * The new structure: - * NSSCMSKeyTransRecipientInfoEx: sizeof(NSSCMSKeyTransRecipientInfo) + - * 1 int, 1 pointer - */ - -struct NSSCMSRecipientInfoStr { - NSSCMSRecipientInfoIDSelector recipientInfoType; - union { - NSSCMSKeyTransRecipientInfo keyTransRecipientInfo; - NSSCMSKeyAgreeRecipientInfo keyAgreeRecipientInfo; - NSSCMSKEKRecipientInfo kekRecipientInfo; - NSSCMSKeyTransRecipientInfoEx keyTransRecipientInfoEx; - } ri; - /* --------- local; not part of encoding --------- */ - NSSCMSMessage * cmsg; /* back pointer to message */ - CERTCertificate * cert; /* recipient's certificate */ -}; - -/* ============================================================================= - * DIGESTED DATA - */ -struct NSSCMSDigestedDataStr { - SECItem version; - SECAlgorithmID digestAlg; - NSSCMSContentInfo contentInfo; - SECItem digest; - /* --------- local; not part of encoding --------- */ - NSSCMSMessage * cmsg; /* back pointer */ - SECItem cdigest; /* calculated digest */ -}; -#define NSS_CMS_DIGESTED_DATA_VERSION_DATA 0 /* what we *create* */ -#define NSS_CMS_DIGESTED_DATA_VERSION_ENCAP 2 /* what we *create* */ - -/* ============================================================================= - * ENCRYPTED DATA - */ -struct NSSCMSEncryptedDataStr { - SECItem version; - NSSCMSContentInfo contentInfo; - NSSCMSAttribute ** unprotectedAttr; /* optional */ - /* --------- local; not part of encoding --------- */ - NSSCMSMessage * cmsg; /* back pointer */ -}; -#define NSS_CMS_ENCRYPTED_DATA_VERSION 0 /* what we *create* */ -#define NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR 2 /* what we *create* */ - -/* ============================================================================= - * FORTEZZA KEA - */ - -/* An enumerated type used to select templates based on the encryption - scenario and data specifics. */ -typedef enum { - NSSCMSKEAInvalid = -1, - NSSCMSKEAUsesSkipjack = 0, - NSSCMSKEAUsesNonSkipjack = 1, - NSSCMSKEAUsesNonSkipjackWithPaddedEncKey = 2 -} NSSCMSKEATemplateSelector; - -/* ### mwelch - S/MIME KEA parameters. These don't really fit here, - but I cannot think of a more appropriate place at this time. */ -struct NSSCMSSMIMEKEAParametersStr { - SECItem originatorKEAKey; /* sender KEA key (encrypted?) */ - SECItem originatorRA; /* random number generated by sender */ - SECItem nonSkipjackIV; /* init'n vector for SkipjackCBC64 - decryption of KEA key if Skipjack - is not the bulk algorithm used on - the message */ - SECItem bulkKeySize; /* if Skipjack is not the bulk - algorithm used on the message, - and the size of the bulk encryption - key is not the same as that of - originatorKEAKey (due to padding - perhaps), this field will contain - the real size of the bulk encryption - key. */ -}; - -/* - * ***************************************************************************** - * ***************************************************************************** - * ***************************************************************************** - */ - -/* - * See comment above about this type not really belonging to CMS. - */ -struct NSSCMSAttributeStr { - /* The following fields make up an encoded Attribute: */ - SECItem type; - SECItem ** values; /* data may or may not be encoded */ - /* The following fields are not part of an encoded Attribute: */ - SECOidData * typeTag; - PRBool encoded; /* when true, values are encoded */ -}; - -#endif /* _CMST_H_ */ diff --git a/security/nss/lib/smime/cmsutil.c b/security/nss/lib/smime/cmsutil.c deleted file mode 100644 index 1765655bb..000000000 --- a/security/nss/lib/smime/cmsutil.c +++ /dev/null @@ -1,401 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * CMS miscellaneous utility functions. - * - * $Id$ - */ - -#include "nssrenam.h" - -#include "cmslocal.h" - -#include "cert.h" -#include "key.h" -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "pk11func.h" -#include "secerr.h" -#include "sechash.h" - -/* - * NSS_CMSArray_SortByDER - sort array of objects by objects' DER encoding - * - * make sure that the order of the objects guarantees valid DER (which must be - * in lexigraphically ascending order for a SET OF); if reordering is necessary it - * will be done in place (in objs). - */ -SECStatus -NSS_CMSArray_SortByDER(void **objs, const SEC_ASN1Template *objtemplate, void **objs2) -{ - PRArenaPool *poolp; - int num_objs; - SECItem **enc_objs; - SECStatus rv = SECFailure; - int i; - - if (objs == NULL) /* already sorted */ - return SECSuccess; - - num_objs = NSS_CMSArray_Count((void **)objs); - if (num_objs == 0 || num_objs == 1) /* already sorted. */ - return SECSuccess; - - poolp = PORT_NewArena (1024); /* arena for temporaries */ - if (poolp == NULL) - return SECFailure; /* no memory; nothing we can do... */ - - /* - * Allocate arrays to hold the individual encodings which we will use - * for comparisons and the reordered attributes as they are sorted. - */ - enc_objs = (SECItem **)PORT_ArenaZAlloc(poolp, (num_objs + 1) * sizeof(SECItem *)); - if (enc_objs == NULL) - goto loser; - - /* DER encode each individual object. */ - for (i = 0; i < num_objs; i++) { - enc_objs[i] = SEC_ASN1EncodeItem(poolp, NULL, objs[i], objtemplate); - if (enc_objs[i] == NULL) - goto loser; - } - enc_objs[num_objs] = NULL; - - /* now compare and sort objs by the order of enc_objs */ - NSS_CMSArray_Sort((void **)enc_objs, NSS_CMSUtil_DERCompare, objs, objs2); - - rv = SECSuccess; - -loser: - PORT_FreeArena (poolp, PR_FALSE); - return rv; -} - -/* - * NSS_CMSUtil_DERCompare - for use with NSS_CMSArray_Sort to - * sort arrays of SECItems containing DER - */ -int -NSS_CMSUtil_DERCompare(void *a, void *b) -{ - SECItem *der1 = (SECItem *)a; - SECItem *der2 = (SECItem *)b; - unsigned int j; - - /* - * Find the lowest (lexigraphically) encoding. One that is - * shorter than all the rest is known to be "less" because each - * attribute is of the same type (a SEQUENCE) and so thus the - * first octet of each is the same, and the second octet is - * the length (or the length of the length with the high bit - * set, followed by the length, which also works out to always - * order the shorter first). Two (or more) that have the - * same length need to be compared byte by byte until a mismatch - * is found. - */ - if (der1->len != der2->len) - return (der1->len < der2->len) ? -1 : 1; - - for (j = 0; j < der1->len; j++) { - if (der1->data[j] == der2->data[j]) - continue; - return (der1->data[j] < der2->data[j]) ? -1 : 1; - } - return 0; -} - -/* - * NSS_CMSAlgArray_GetIndexByAlgID - find a specific algorithm in an array of - * algorithms. - * - * algorithmArray - array of algorithm IDs - * algid - algorithmid of algorithm to pick - * - * Returns: - * An integer containing the index of the algorithm in the array or -1 if - * algorithm was not found. - */ -int -NSS_CMSAlgArray_GetIndexByAlgID(SECAlgorithmID **algorithmArray, SECAlgorithmID *algid) -{ - int i; - - if (algorithmArray == NULL || algorithmArray[0] == NULL) - return -1; - - for (i = 0; algorithmArray[i] != NULL; i++) { - if (SECOID_CompareAlgorithmID(algorithmArray[i], algid) == SECEqual) - break; /* bingo */ - } - - if (algorithmArray[i] == NULL) - return -1; /* not found */ - - return i; -} - -/* - * NSS_CMSAlgArray_GetIndexByAlgTag - find a specific algorithm in an array of - * algorithms. - * - * algorithmArray - array of algorithm IDs - * algtag - algorithm tag of algorithm to pick - * - * Returns: - * An integer containing the index of the algorithm in the array or -1 if - * algorithm was not found. - */ -int -NSS_CMSAlgArray_GetIndexByAlgTag(SECAlgorithmID **algorithmArray, - SECOidTag algtag) -{ - SECOidData *algid; - int i = -1; - - if (algorithmArray == NULL || algorithmArray[0] == NULL) - return i; - -#ifdef ORDER_N_SQUARED - for (i = 0; algorithmArray[i] != NULL; i++) { - algid = SECOID_FindOID(&(algorithmArray[i]->algorithm)); - if (algid->offset == algtag) - break; /* bingo */ - } -#else - algid = SECOID_FindOIDByTag(algtag); - if (!algid) - return i; - for (i = 0; algorithmArray[i] != NULL; i++) { - if (SECITEM_ItemsAreEqual(&algorithmArray[i]->algorithm, &algid->oid)) - break; /* bingo */ - } -#endif - - if (algorithmArray[i] == NULL) - return -1; /* not found */ - - return i; -} - -const SECHashObject * -NSS_CMSUtil_GetHashObjByAlgID(SECAlgorithmID *algid) -{ - SECOidTag oidTag = SECOID_FindOIDTag(&(algid->algorithm)); - const SECHashObject *digobj = HASH_GetHashObjectByOidTag(oidTag); - - return digobj; -} - -/* - * XXX I would *really* like to not have to do this, but the current - * signing interface gives me little choice. - */ -SECOidTag -NSS_CMSUtil_MakeSignatureAlgorithm(SECOidTag hashalg, SECOidTag encalg) -{ - switch (encalg) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - switch (hashalg) { - case SEC_OID_MD2: - return SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; - case SEC_OID_MD5: - return SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; - case SEC_OID_SHA1: - return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; - case SEC_OID_SHA256: - return SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; - case SEC_OID_SHA384: - return SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; - case SEC_OID_SHA512: - return SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; - default: - return SEC_OID_UNKNOWN; - } - case SEC_OID_ANSIX9_DSA_SIGNATURE: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_DSS: - switch (hashalg) { - case SEC_OID_SHA1: - return SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; - default: - return SEC_OID_UNKNOWN; - } - case SEC_OID_ANSIX962_EC_PUBLIC_KEY: - switch (hashalg) { - case SEC_OID_SHA1: - return SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; - default: - return SEC_OID_UNKNOWN; - } - default: - break; - } - - return encalg; /* maybe it is already the right algid */ -} - -const SEC_ASN1Template * -NSS_CMSUtil_GetTemplateByTypeTag(SECOidTag type) -{ - const SEC_ASN1Template *template; - extern const SEC_ASN1Template NSSCMSSignedDataTemplate[]; - extern const SEC_ASN1Template NSSCMSEnvelopedDataTemplate[]; - extern const SEC_ASN1Template NSSCMSEncryptedDataTemplate[]; - extern const SEC_ASN1Template NSSCMSDigestedDataTemplate[]; - - switch (type) { - case SEC_OID_PKCS7_SIGNED_DATA: - template = NSSCMSSignedDataTemplate; - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - template = NSSCMSEnvelopedDataTemplate; - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - template = NSSCMSEncryptedDataTemplate; - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - template = NSSCMSDigestedDataTemplate; - break; - default: - case SEC_OID_PKCS7_DATA: - template = NULL; - break; - } - return template; -} - -size_t -NSS_CMSUtil_GetSizeByTypeTag(SECOidTag type) -{ - size_t size; - - switch (type) { - case SEC_OID_PKCS7_SIGNED_DATA: - size = sizeof(NSSCMSSignedData); - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - size = sizeof(NSSCMSEnvelopedData); - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - size = sizeof(NSSCMSEncryptedData); - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - size = sizeof(NSSCMSDigestedData); - break; - default: - case SEC_OID_PKCS7_DATA: - size = 0; - break; - } - return size; -} - -NSSCMSContentInfo * -NSS_CMSContent_GetContentInfo(void *msg, SECOidTag type) -{ - NSSCMSContent c; - NSSCMSContentInfo *cinfo = NULL; - - if (!msg) - return cinfo; - c.pointer = msg; - switch (type) { - case SEC_OID_PKCS7_SIGNED_DATA: - cinfo = &(c.signedData->contentInfo); - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - cinfo = &(c.envelopedData->contentInfo); - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - cinfo = &(c.encryptedData->contentInfo); - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - cinfo = &(c.digestedData->contentInfo); - break; - default: - cinfo = NULL; - } - return cinfo; -} - -const char * -NSS_CMSUtil_VerificationStatusToString(NSSCMSVerificationStatus vs) -{ - switch (vs) { - case NSSCMSVS_Unverified: return "Unverified"; - case NSSCMSVS_GoodSignature: return "GoodSignature"; - case NSSCMSVS_BadSignature: return "BadSignature"; - case NSSCMSVS_DigestMismatch: return "DigestMismatch"; - case NSSCMSVS_SigningCertNotFound: return "SigningCertNotFound"; - case NSSCMSVS_SigningCertNotTrusted: return "SigningCertNotTrusted"; - case NSSCMSVS_SignatureAlgorithmUnknown: return "SignatureAlgorithmUnknown"; - case NSSCMSVS_SignatureAlgorithmUnsupported: return "SignatureAlgorithmUnsupported"; - case NSSCMSVS_MalformedSignature: return "MalformedSignature"; - case NSSCMSVS_ProcessingError: return "ProcessingError"; - default: return "Unknown"; - } -} - -SECStatus -NSS_CMSDEREncode(NSSCMSMessage *cmsg, SECItem *input, SECItem *derOut, - PLArenaPool *arena) -{ - NSSCMSEncoderContext *ecx; - SECStatus rv = SECSuccess; - if (!cmsg || !derOut || !arena) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - ecx = NSS_CMSEncoder_Start(cmsg, 0, 0, derOut, arena, 0, 0, 0, 0, 0, 0); - if (!ecx) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - if (input) { - rv = NSS_CMSEncoder_Update(ecx, (const char*)input->data, input->len); - if (rv) { - PORT_SetError(SEC_ERROR_BAD_DATA); - } - } - rv |= NSS_CMSEncoder_Finish(ecx); - if (rv) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - } - return rv; -} diff --git a/security/nss/lib/smime/config.mk b/security/nss/lib/smime/config.mk deleted file mode 100644 index 236dd375b..000000000 --- a/security/nss/lib/smime/config.mk +++ /dev/null @@ -1,99 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# 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 the Initial Developer are Copyright (C) 1994-2000 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -RELEASE_LIBS = $(TARGETS) - -ifeq (,$(filter-out WIN%,$(OS_TARGET))) - -# don't want the 32 in the shared library name -SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) -IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX) - -RES = $(OBJDIR)/smime.res -RESNAME = smime.rc - -ifdef NS_USE_GCC -EXTRA_SHARED_LIBS += \ - -L$(DIST)/lib \ - -lnss3 \ - -L$(NSPR_LIB_DIR) \ - -lplc4 \ - -lplds4 \ - -lnspr4 \ - $(NULL) -else # ! NS_USE_GCC -EXTRA_SHARED_LIBS += \ - $(DIST)/lib/nss3.lib \ - $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \ - $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \ - $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \ - $(NULL) -endif # NS_USE_GCC - -else - -EXTRA_SHARED_LIBS += \ - -L$(DIST)/lib \ - -lnss3 \ - -L$(NSPR_LIB_DIR) \ - -lplc4 \ - -lplds4 \ - -lnspr4 \ - $(NULL) - -ifeq ($(OS_ARCH), Darwin) -EXTRA_SHARED_LIBS += -dylib_file @executable_path/libsoftokn3.dylib:$(DIST)/lib/libsoftokn3.dylib -endif - -endif - - -SHARED_LIBRARY_LIBS = \ - $(DIST)/lib/$(LIB_PREFIX)pkcs12.$(LIB_SUFFIX) \ - $(DIST)/lib/$(LIB_PREFIX)pkcs7.$(LIB_SUFFIX) \ - $(NULL) - -SHARED_LIBRARY_DIRS = \ - ../pkcs12 \ - ../pkcs7 \ - $(NULL) - -ifeq ($(OS_TARGET),SunOS) -# The -R '$ORIGIN' linker option instructs this library to search for its -# dependencies in the same directory where it resides. -MKSHLIB += -R '$$ORIGIN' -endif diff --git a/security/nss/lib/smime/manifest.mn b/security/nss/lib/smime/manifest.mn deleted file mode 100644 index d0b4db607..000000000 --- a/security/nss/lib/smime/manifest.mn +++ /dev/null @@ -1,81 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# 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 the Initial Developer are Copyright (C) 1994-2000 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -CORE_DEPTH = ../../.. - -EXPORTS = \ - cms.h \ - cmst.h \ - smime.h \ - cmsreclist.h \ - $(NULL) - -PRIVATE_EXPORTS = \ - cmslocal.h \ - $(NULL) - -MODULE = nss -MAPFILE = $(OBJDIR)/smime.def - -CSRCS = \ - cmsarray.c \ - cmsasn1.c \ - cmsattr.c \ - cmscinfo.c \ - cmscipher.c \ - cmsdecode.c \ - cmsdigdata.c \ - cmsdigest.c \ - cmsencdata.c \ - cmsencode.c \ - cmsenvdata.c \ - cmsmessage.c \ - cmspubkey.c \ - cmsrecinfo.c \ - cmsreclist.c \ - cmssigdata.c \ - cmssiginfo.c \ - cmsutil.c \ - smimemessage.c \ - smimeutil.c \ - smimever.c \ - $(NULL) - -REQUIRES = dbm - -LIBRARY_NAME = smime -LIBRARY_VERSION = 3 diff --git a/security/nss/lib/smime/smime.def b/security/nss/lib/smime/smime.def deleted file mode 100644 index 91e77c61a..000000000 --- a/security/nss/lib/smime/smime.def +++ /dev/null @@ -1,268 +0,0 @@ -;+# -;+# ***** BEGIN LICENSE BLOCK ***** -;+# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -;+# -;+# 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 the Initial Developer are Copyright (C) 2000 -;+# the Initial Developer. All Rights Reserved. -;+# -;+# Contributor(s): -;+# -;+# Alternatively, the contents of this file may be used under the terms of -;+# either the GNU General Public License Version 2 or later (the "GPL"), or -;+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -;+# in which case the provisions of the GPL or the LGPL are applicable instead -;+# of those above. If you wish to allow use of your version of this file only -;+# under the terms of either the GPL or the LGPL, and not to allow others to -;+# use your version of this file under the terms of the MPL, indicate your -;+# decision by deleting the provisions above and replace them with the notice -;+# and other provisions required by the GPL or the LGPL. If you do not delete -;+# the provisions above, a recipient may use your version of this file under -;+# the terms of any one of the MPL, the GPL or the LGPL. -;+# -;+# ***** END LICENSE BLOCK ***** -;+# -;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS -;+# 1. For all unix platforms, the string ";-" means "remove this line" -;+# 2. For all unix platforms, the string " DATA " will be removed from any -;+# line on which it occurs. -;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. -;+# On AIX, lines containing ";+" will be removed. -;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed. -;+# 5. For all unix platforms, after the above processing has taken place, -;+# all characters after the first ";" on the line will be removed. -;+# And for AIX, the first ";" will also be removed. -;+# This file is passed directly to windows. Since ';' is a comment, all UNIX -;+# directives are hidden behind ";", ";+", and ";-" -;+ -;+NSS_3.2 { # NSS 3.2 release -;+ global: -LIBRARY smime3 ;- -EXPORTS ;- -NSS_CMSContentInfo_GetBulkKey; -NSS_CMSContentInfo_GetBulkKeySize; -NSS_CMSContentInfo_GetContent; -NSS_CMSContentInfo_GetContentEncAlgTag; -NSS_CMSContentInfo_GetContentTypeTag; -NSS_CMSContentInfo_SetBulkKey; -NSS_CMSContentInfo_SetContent; -NSS_CMSContentInfo_SetContentEncAlg; -NSS_CMSContentInfo_SetContent_Data; -NSS_CMSContentInfo_SetContent_DigestedData; -NSS_CMSContentInfo_SetContent_EncryptedData; -NSS_CMSContentInfo_SetContent_EnvelopedData; -NSS_CMSContentInfo_SetContent_SignedData; -NSS_CMSDEREncode; -NSS_CMSDecoder_Cancel; -NSS_CMSDecoder_Finish; -NSS_CMSDecoder_Start; -NSS_CMSDecoder_Update; -NSS_CMSDigestContext_Cancel; -NSS_CMSDigestContext_FinishMultiple; -NSS_CMSDigestContext_FinishSingle; -NSS_CMSDigestContext_StartMultiple; -NSS_CMSDigestContext_StartSingle; -NSS_CMSDigestContext_Update; -NSS_CMSDigestedData_Create; -NSS_CMSDigestedData_Destroy; -NSS_CMSDigestedData_GetContentInfo; -NSS_CMSEncoder_Cancel; -NSS_CMSEncoder_Finish; -NSS_CMSEncoder_Start; -NSS_CMSEncoder_Update; -NSS_CMSEncryptedData_Create; -NSS_CMSEncryptedData_Destroy; -NSS_CMSEncryptedData_GetContentInfo; -NSS_CMSEnvelopedData_AddRecipient; -NSS_CMSEnvelopedData_Create; -NSS_CMSEnvelopedData_Destroy; -NSS_CMSEnvelopedData_GetContentInfo; -NSS_CMSMessage_ContentLevel; -NSS_CMSMessage_ContentLevelCount; -NSS_CMSMessage_Copy; -NSS_CMSMessage_Create; -NSS_CMSMessage_CreateFromDER; -NSS_CMSMessage_Destroy; -NSS_CMSMessage_GetContent; -NSS_CMSMessage_GetContentInfo; -NSS_CMSRecipientInfo_Create; -NSS_CMSRecipientInfo_Destroy; -NSS_CMSSignedData_AddCertChain; -NSS_CMSSignedData_AddCertList; -NSS_CMSSignedData_AddCertificate; -NSS_CMSSignedData_AddDigest; -NSS_CMSSignedData_AddSignerInfo; -NSS_CMSSignedData_Create; -NSS_CMSSignedData_CreateCertsOnly; -NSS_CMSSignedData_Destroy; -NSS_CMSSignedData_GetContentInfo; -NSS_CMSSignedData_GetDigestAlgs; -NSS_CMSSignedData_GetSignerInfo; -NSS_CMSSignedData_HasDigests; -NSS_CMSSignedData_ImportCerts; -NSS_CMSSignedData_SetDigests; -NSS_CMSSignedData_SignerInfoCount; -NSS_CMSSignedData_VerifyCertsOnly; -NSS_CMSSignedData_VerifySignerInfo; -NSS_CMSSignerInfo_AddSMIMECaps; -NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs; -NSS_CMSSignerInfo_AddSigningTime; -NSS_CMSSignerInfo_Create; -NSS_CMSSignerInfo_Destroy; -NSS_CMSSignerInfo_GetCertList; -NSS_CMSSignerInfo_GetSignerCommonName; -NSS_CMSSignerInfo_GetSignerEmailAddress; -NSS_CMSSignerInfo_GetSigningCertificate; -NSS_CMSSignerInfo_GetSigningTime; -NSS_CMSSignerInfo_GetVerificationStatus; -NSS_CMSSignerInfo_GetVersion; -NSS_CMSSignerInfo_IncludeCerts; -NSS_CMSUtil_VerificationStatusToString; -NSS_SMIMEUtil_FindBulkAlgForRecipients; -CERT_DecodeCertPackage; -SEC_PKCS7AddRecipient; -SEC_PKCS7AddSigningTime; -SEC_PKCS7ContentType; -SEC_PKCS7CreateData; -SEC_PKCS7CreateEncryptedData; -SEC_PKCS7CreateEnvelopedData; -SEC_PKCS7CreateSignedData; -SEC_PKCS7DecodeItem; -SEC_PKCS7DecoderFinish; -SEC_PKCS7DecoderStart; -SEC_PKCS7DecoderUpdate; -SEC_PKCS7DecryptContents; -SEC_PKCS7DestroyContentInfo; -SEC_PKCS7EncoderFinish; -SEC_PKCS7EncoderStart; -SEC_PKCS7EncoderUpdate; -SEC_PKCS7GetCertificateList; -SEC_PKCS7GetContent; -SEC_PKCS7GetEncryptionAlgorithm; -SEC_PKCS7IncludeCertChain; -SEC_PKCS7IsContentEmpty; -SEC_PKCS7VerifySignature; -SEC_PKCS12AddCertAndKey; -SEC_PKCS12AddPasswordIntegrity; -SEC_PKCS12CreateExportContext; -SEC_PKCS12CreatePasswordPrivSafe; -SEC_PKCS12CreateUnencryptedSafe; -SEC_PKCS12EnableCipher; -SEC_PKCS12Encode; -SEC_PKCS12DecoderImportBags; -SEC_PKCS12DecoderFinish; -SEC_PKCS12DecoderStart; -SEC_PKCS12DecoderUpdate; -SEC_PKCS12DecoderValidateBags; -SEC_PKCS12DecoderVerify; -SEC_PKCS12DestroyExportContext; -SEC_PKCS12IsEncryptionAllowed; -SEC_PKCS12SetPreferredCipher; -;+ local: -;+ *; -;+}; -;+NSS_3.2.1 { # NSS 3.2.1 release -;+ global: -NSSSMIME_VersionCheck; -;+ local: -;+ *; -;+}; -;+NSS_3.3 { # NSS 3.3 release -;+ global: -SEC_PKCS7AddCertificate; -SEC_PKCS7CreateCertsOnly; -SEC_PKCS7Encode; -;+ local: -;+ *; -;+}; -;+NSS_3.4 { # NSS 3.4 release -;+ global: -CERT_DecodeCertFromPackage; -NSS_CMSMessage_IsSigned; -NSS_CMSSignedData_SetDigestValue; -NSS_SMIMESignerInfo_SaveSMIMEProfile; -SEC_PKCS12DecoderGetCerts; -SEC_PKCS7ContainsCertsOrCrls; -SEC_PKCS7ContentIsEncrypted; -SEC_PKCS7ContentIsSigned; -SEC_PKCS7CopyContentInfo; -SEC_PKCS7GetSignerCommonName; -SEC_PKCS7GetSignerEmailAddress; -SEC_PKCS7GetSigningTime; -SEC_PKCS7SetContent; -SEC_PKCS7VerifyDetachedSignature; -SECMIME_DecryptionAllowed; -;+ local: -;+ *; -;+}; -;+NSS_3.4.1 { # NSS 3.4.1 release -;+ global: -NSS_CMSMessage_IsEncrypted; -;+ local: -;+ *; -;+}; -;+NSS_3.6 { # NSS 3.6 release -;+ global: -NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs; -NSS_CMSSignerInfo_CreateWithSubjKeyID; -;+ local: -;+ *; -;+}; -;+NSS_3.7 { # NSS 3.7 release -;+ global: -NSS_CMSRecipientInfo_CreateWithSubjKeyID; -NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert; -;+ local: -;+ *; -;+}; -;+NSS_3.7.2 { # NSS 3.7.2 release -;+ global: -NSS_CMSRecipientInfo_WrapBulkKey; -NSS_CMSRecipientInfo_UnwrapBulkKey; -;+ local: -;+ *; -;+}; -;+NSS_3.8 { # NSS 3.8 release -;+ global: -NSS_CMSRecipientInfo_CreateNew; -NSS_CMSRecipientInfo_CreateFromDER; -NSS_CMSRecipientInfo_Encode; -NSS_CMSRecipientInfo_GetCertAndKey; -SEC_PKCS12DecoderSetTargetTokenCAs; -;+ local: -;+ *; -;+}; -;+NSS_3.9 { # NSS 3.9 release -;+ global: -SEC_PKCS7DecoderAbort; -SEC_PKCS7EncoderAbort; -;+ local: -;+ *; -;+}; -;+NSS_3.9.3 { # NSS 3.9.3 release -;+ global: -CERT_ConvertAndDecodeCertificate; -SEC_PKCS7EncodeItem; -;+ local: -;+ *; -;+}; -;+NSS_3.10 { # NSS 3.10 release -;+ global: -SEC_PKCS12DecoderIterateInit; -SEC_PKCS12DecoderIterateNext; -;+ local: -;+ *; -;+}; diff --git a/security/nss/lib/smime/smime.h b/security/nss/lib/smime/smime.h deleted file mode 100644 index 5fc659023..000000000 --- a/security/nss/lib/smime/smime.h +++ /dev/null @@ -1,156 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * Header file for routines specific to S/MIME. Keep things that are pure - * pkcs7 out of here; this is for S/MIME policy, S/MIME interoperability, etc. - * - * $Id$ - */ - -#ifndef _SECMIME_H_ -#define _SECMIME_H_ 1 - -#include "cms.h" - - -/************************************************************************/ -SEC_BEGIN_PROTOS - -/* - * Initialize the local recording of the user S/MIME cipher preferences. - * This function is called once for each cipher, the order being - * important (first call records greatest preference, and so on). - * When finished, it is called with a "which" of CIPHER_FAMILID_MASK. - * If the function is called again after that, it is assumed that - * the preferences are being reset, and the old preferences are - * discarded. - * - * XXX This is for a particular user, and right now the storage is - * XXX local, static. The preference should be stored elsewhere to allow - * XXX for multiple uses of one library? How does SSL handle this; - * XXX it has something similar? - * - * - The "which" values are defined in ciferfam.h (the SMIME_* values, - * for example SMIME_DES_CBC_56). - * - If "on" is non-zero then the named cipher is enabled, otherwise - * it is disabled. (It is not necessary to call the function for - * ciphers that are disabled, however, as that is the default.) - * - * If the cipher preference is successfully recorded, SECSuccess - * is returned. Otherwise SECFailure is returned. The only errors - * are due to failure allocating memory or bad parameters/calls: - * SEC_ERROR_XXX ("which" is not in the S/MIME cipher family) - * SEC_ERROR_XXX (function is being called more times than there - * are known/expected ciphers) - */ -extern SECStatus NSS_SMIMEUtil_EnableCipher(long which, int on); - -/* - * Initialize the local recording of the S/MIME policy. - * This function is called to allow/disallow a particular cipher. - * - * XXX This is for a the current module, I think, so local, static storage - * XXX is okay. Is that correct, or could multiple uses of the same - * XXX library expect to operate under different policies? - * - * - The "which" values are defined in ciferfam.h (the SMIME_* values, - * for example SMIME_DES_CBC_56). - * - If "on" is non-zero then the named cipher is enabled, otherwise - * it is disabled. - */ -extern SECStatus NSS_SMIMEUtils_AllowCipher(long which, int on); - -/* - * Does the current policy allow S/MIME decryption of this particular - * algorithm and keysize? - */ -extern PRBool NSS_SMIMEUtil_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key); - -/* - * Does the current policy allow *any* S/MIME encryption (or decryption)? - * - * This tells whether or not *any* S/MIME encryption can be done, - * according to policy. Callers may use this to do nicer user interface - * (say, greying out a checkbox so a user does not even try to encrypt - * a message when they are not allowed to) or for any reason they want - * to check whether S/MIME encryption (or decryption, for that matter) - * may be done. - * - * It takes no arguments. The return value is a simple boolean: - * PR_TRUE means encryption (or decryption) is *possible* - * (but may still fail due to other reasons, like because we cannot - * find all the necessary certs, etc.; PR_TRUE is *not* a guarantee) - * PR_FALSE means encryption (or decryption) is not permitted - * - * There are no errors from this routine. - */ -extern PRBool NSS_SMIMEUtil_EncryptionPossible(void); - -/* - * NSS_SMIMEUtil_CreateSMIMECapabilities - get S/MIME capabilities attr value - * - * scans the list of allowed and enabled ciphers and construct a PKCS9-compliant - * S/MIME capabilities attribute value. - */ -extern SECStatus NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool includeFortezzaCiphers); - -/* - * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value - */ -extern SECStatus NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert); - -/* - * NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value using MS oid - */ -extern SECStatus NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert); - -/* - * NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference - find cert marked by EncryptionKeyPreference - * attribute - */ -extern CERTCertificate *NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(CERTCertDBHandle *certdb, SECItem *DERekp); - -/* - * NSS_SMIMEUtil_FindBulkAlgForRecipients - find bulk algorithm suitable for all recipients - */ -extern SECStatus -NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts, SECOidTag *bulkalgtag, int *keysize); - -/************************************************************************/ -SEC_END_PROTOS - -#endif /* _SECMIME_H_ */ diff --git a/security/nss/lib/smime/smime.rc b/security/nss/lib/smime/smime.rc deleted file mode 100644 index 05fb11bfa..000000000 --- a/security/nss/lib/smime/smime.rc +++ /dev/null @@ -1,101 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nss.h" -#include <winver.h> - -#define MY_LIBNAME "smime" -#define MY_FILEDESCRIPTION "NSS S/MIME Library" - -#define STRINGIZE(x) #x -#define STRINGIZE2(x) STRINGIZE(x) -#define NSS_VMAJOR_STR STRINGIZE2(NSS_VMAJOR) - -#ifdef _DEBUG -#define MY_DEBUG_STR " (debug)" -#define MY_FILEFLAGS_1 VS_FF_DEBUG -#else -#define MY_DEBUG_STR "" -#define MY_FILEFLAGS_1 0x0L -#endif -#if NSS_BETA -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE -#else -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1 -#endif - -#ifdef WINNT -#define MY_FILEOS VOS_NT_WINDOWS32 -#else -#define MY_FILEOS VOS__WINDOWS32 -#endif - -#define MY_INTERNAL_NAME MY_LIBNAME NSS_VMAJOR_STR - -///////////////////////////////////////////////////////////////////////////// -// -// Version-information resource -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0 - PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK - FILEFLAGS MY_FILEFLAGS_2 - FILEOS MY_FILEOS - FILETYPE VFT_DLL - FILESUBTYPE 0x0L // not used - -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904B0" // Lang=US English, CharSet=Unicode - BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" - VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" - VALUE "FileVersion", NSS_VERSION "\0" - VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0" - VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" - VALUE "ProductName", "Network Security Services\0" - VALUE "ProductVersion", NSS_VERSION "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/security/nss/lib/smime/smimemessage.c b/security/nss/lib/smime/smimemessage.c deleted file mode 100644 index 76e709332..000000000 --- a/security/nss/lib/smime/smimemessage.c +++ /dev/null @@ -1,218 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * SMIME message methods - * - * $Id$ - */ - -#include "cmslocal.h" -#include "smime.h" - -#include "cert.h" -#include "key.h" -#include "secasn1.h" -#include "secitem.h" -#include "secoid.h" -#include "pk11func.h" -#include "prtime.h" -#include "secerr.h" - - -#if 0 -/* - * NSS_SMIMEMessage_CreateEncrypted - start an S/MIME encrypting context. - * - * "scert" is the cert for the sender. It will be checked for validity. - * "rcerts" are the certs for the recipients. They will also be checked. - * - * "certdb" is the cert database to use for verifying the certs. - * It can be NULL if a default database is available (like in the client). - * - * This function already does all of the stuff specific to S/MIME protocol - * and local policy; the return value just needs to be passed to - * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data, - * and finally to SEC_PKCS7DestroyContentInfo(). - * - * An error results in a return value of NULL and an error set. - * (Retrieve specific errors via PORT_GetError()/XP_GetError().) - */ -NSSCMSMessage * -NSS_SMIMEMessage_CreateEncrypted(CERTCertificate *scert, - CERTCertificate **rcerts, - CERTCertDBHandle *certdb, - PK11PasswordFunc pwfn, - void *pwfn_arg) -{ - NSSCMSMessage *cmsg; - long cipher; - SECOidTag encalg; - int keysize; - int mapi, rci; - - cipher = smime_choose_cipher (scert, rcerts); - if (cipher < 0) - return NULL; - - mapi = smime_mapi_by_cipher (cipher); - if (mapi < 0) - return NULL; - - /* - * XXX This is stretching it -- CreateEnvelopedData should probably - * take a cipher itself of some sort, because we cannot know what the - * future will bring in terms of parameters for each type of algorithm. - * For example, just an algorithm and keysize is *not* sufficient to - * fully specify the usage of RC5 (which also needs to know rounds and - * block size). Work this out into a better API! - */ - encalg = smime_cipher_map[mapi].algtag; - keysize = smime_keysize_by_cipher (cipher); - if (keysize < 0) - return NULL; - - cinfo = SEC_PKCS7CreateEnvelopedData (scert, certUsageEmailRecipient, - certdb, encalg, keysize, - pwfn, pwfn_arg); - if (cinfo == NULL) - return NULL; - - for (rci = 0; rcerts[rci] != NULL; rci++) { - if (rcerts[rci] == scert) - continue; - if (SEC_PKCS7AddRecipient (cinfo, rcerts[rci], certUsageEmailRecipient, - NULL) != SECSuccess) { - SEC_PKCS7DestroyContentInfo (cinfo); - return NULL; - } - } - - return cinfo; -} - - -/* - * Start an S/MIME signing context. - * - * "scert" is the cert that will be used to sign the data. It will be - * checked for validity. - * - * "ecert" is the signer's encryption cert. If it is different from - * scert, then it will be included in the signed message so that the - * recipient can save it for future encryptions. - * - * "certdb" is the cert database to use for verifying the cert. - * It can be NULL if a default database is available (like in the client). - * - * "digestalg" names the digest algorithm (e.g. SEC_OID_SHA1). - * XXX There should be SECMIME functions for hashing, or the hashing should - * be built into this interface, which we would like because we would - * support more smartcards that way, and then this argument should go away.) - * - * "digest" is the actual digest of the data. It must be provided in - * the case of detached data or NULL if the content will be included. - * - * This function already does all of the stuff specific to S/MIME protocol - * and local policy; the return value just needs to be passed to - * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data, - * and finally to SEC_PKCS7DestroyContentInfo(). - * - * An error results in a return value of NULL and an error set. - * (Retrieve specific errors via PORT_GetError()/XP_GetError().) - */ - -NSSCMSMessage * -NSS_SMIMEMessage_CreateSigned(CERTCertificate *scert, - CERTCertificate *ecert, - CERTCertDBHandle *certdb, - SECOidTag digestalgtag, - SECItem *digest, - PK11PasswordFunc pwfn, - void *pwfn_arg) -{ - NSSCMSMessage *cmsg; - NSSCMSSignedData *sigd; - NSSCMSSignerInfo *signerinfo; - - /* See note in header comment above about digestalg. */ - /* Doesn't explain this. PORT_Assert (digestalgtag == SEC_OID_SHA1); */ - - cmsg = NSS_CMSMessage_Create(NULL); - if (cmsg == NULL) - return NULL; - - sigd = NSS_CMSSignedData_Create(cmsg); - if (sigd == NULL) - goto loser; - - /* create just one signerinfo */ - signerinfo = NSS_CMSSignerInfo_Create(cmsg, scert, digestalgtag); - if (signerinfo == NULL) - goto loser; - - /* Add the signing time to the signerinfo. */ - if (NSS_CMSSignerInfo_AddSigningTime(signerinfo, PR_Now()) != SECSuccess) - goto loser; - - /* and add the SMIME profile */ - if (NSS_SMIMESignerInfo_AddSMIMEProfile(signerinfo, scert) != SECSuccess) - goto loser; - - /* now add the signerinfo to the signeddata */ - if (NSS_CMSSignedData_AddSignerInfo(sigd, signerinfo) != SECSuccess) - goto loser; - - /* include the signing cert and its entire chain */ - /* note that there are no checks for duplicate certs in place, as all the */ - /* essential data structures (like set of certificate) are not there */ - if (NSS_CMSSignedData_AddCertChain(sigd, scert) != SECSuccess) - goto loser; - - /* If the encryption cert and the signing cert differ, then include - * the encryption cert too. */ - if ( ( ecert != NULL ) && ( ecert != scert ) ) { - if (NSS_CMSSignedData_AddCertificate(sigd, ecert) != SECSuccess) - goto loser; - } - - return cmsg; -loser: - if (cmsg) - NSS_CMSMessage_Destroy(cmsg); - return NULL; -} -#endif diff --git a/security/nss/lib/smime/smimesym.c b/security/nss/lib/smime/smimesym.c deleted file mode 100644 index e7bb771e5..000000000 --- a/security/nss/lib/smime/smimesym.c +++ /dev/null @@ -1,8 +0,0 @@ -extern void SEC_PKCS7DecodeItem(); -extern void SEC_PKCS7DestroyContentInfo(); - -smime_CMDExports() { - SEC_PKCS7DecodeItem(); - SEC_PKCS7DestroyContentInfo(); -} - diff --git a/security/nss/lib/smime/smimeutil.c b/security/nss/lib/smime/smimeutil.c deleted file mode 100644 index 6fb10ec07..000000000 --- a/security/nss/lib/smime/smimeutil.c +++ /dev/null @@ -1,784 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * Stuff specific to S/MIME policy and interoperability. - * - * $Id$ - */ - -#include "secmime.h" -#include "secoid.h" -#include "pk11func.h" -#include "ciferfam.h" /* for CIPHER_FAMILY symbols */ -#include "secasn1.h" -#include "secitem.h" -#include "cert.h" -#include "key.h" -#include "secerr.h" -#include "cms.h" -#include "nss.h" - -SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate) -SEC_ASN1_MKSUB(SEC_OctetStringTemplate) -SEC_ASN1_CHOOSER_DECLARE(CERT_IssuerAndSNTemplate) - -/* various integer's ASN.1 encoding */ -static unsigned char asn1_int40[] = { SEC_ASN1_INTEGER, 0x01, 0x28 }; -static unsigned char asn1_int64[] = { SEC_ASN1_INTEGER, 0x01, 0x40 }; -static unsigned char asn1_int128[] = { SEC_ASN1_INTEGER, 0x02, 0x00, 0x80 }; - -/* RC2 algorithm parameters (used in smime_cipher_map) */ -static SECItem param_int40 = { siBuffer, asn1_int40, sizeof(asn1_int40) }; -static SECItem param_int64 = { siBuffer, asn1_int64, sizeof(asn1_int64) }; -static SECItem param_int128 = { siBuffer, asn1_int128, sizeof(asn1_int128) }; - -/* - * XXX Would like the "parameters" field to be a SECItem *, but the - * encoder is having trouble with optional pointers to an ANY. Maybe - * once that is fixed, can change this back... - */ -typedef struct { - SECItem capabilityID; - SECItem parameters; - long cipher; /* optimization */ -} NSSSMIMECapability; - -static const SEC_ASN1Template NSSSMIMECapabilityTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSSMIMECapability) }, - { SEC_ASN1_OBJECT_ID, - offsetof(NSSSMIMECapability,capabilityID), }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY, - offsetof(NSSSMIMECapability,parameters), }, - { 0, } -}; - -static const SEC_ASN1Template NSSSMIMECapabilitiesTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, NSSSMIMECapabilityTemplate } -}; - -/* - * NSSSMIMEEncryptionKeyPreference - if we find one of these, it needs to prompt us - * to store this and only this certificate permanently for the sender email address. - */ -typedef enum { - NSSSMIMEEncryptionKeyPref_IssuerSN, - NSSSMIMEEncryptionKeyPref_RKeyID, - NSSSMIMEEncryptionKeyPref_SubjectKeyID -} NSSSMIMEEncryptionKeyPrefSelector; - -typedef struct { - NSSSMIMEEncryptionKeyPrefSelector selector; - union { - CERTIssuerAndSN *issuerAndSN; - NSSCMSRecipientKeyIdentifier *recipientKeyID; - SECItem *subjectKeyID; - } id; -} NSSSMIMEEncryptionKeyPreference; - -extern const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[]; - -static const SEC_ASN1Template smime_encryptionkeypref_template[] = { - { SEC_ASN1_CHOICE, - offsetof(NSSSMIMEEncryptionKeyPreference,selector), NULL, - sizeof(NSSSMIMEEncryptionKeyPreference) }, - { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, - offsetof(NSSSMIMEEncryptionKeyPreference,id.issuerAndSN), - SEC_ASN1_SUB(CERT_IssuerAndSNTemplate), - NSSSMIMEEncryptionKeyPref_IssuerSN }, - { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(NSSSMIMEEncryptionKeyPreference,id.recipientKeyID), - NSSCMSRecipientKeyIdentifierTemplate, - NSSSMIMEEncryptionKeyPref_IssuerSN }, - { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2, - offsetof(NSSSMIMEEncryptionKeyPreference,id.subjectKeyID), - SEC_ASN1_SUB(SEC_OctetStringTemplate), - NSSSMIMEEncryptionKeyPref_SubjectKeyID }, - { 0, } -}; - -/* smime_cipher_map - map of SMIME symmetric "ciphers" to algtag & parameters */ -typedef struct { - unsigned long cipher; - SECOidTag algtag; - SECItem *parms; - PRBool enabled; /* in the user's preferences */ - PRBool allowed; /* per export policy */ -} smime_cipher_map_entry; - -/* global: list of supported SMIME symmetric ciphers, ordered roughly by increasing strength */ -static smime_cipher_map_entry smime_cipher_map[] = { -/* cipher algtag parms enabled allowed */ -/* ---------------------------------------------------------------------------------- */ - { SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, ¶m_int40, PR_TRUE, PR_TRUE }, - { SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL, PR_TRUE, PR_TRUE }, - { SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, ¶m_int64, PR_TRUE, PR_TRUE }, - { SMIME_RC2_CBC_128, SEC_OID_RC2_CBC, ¶m_int128, PR_TRUE, PR_TRUE }, - { SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL, PR_TRUE, PR_TRUE }, - { SMIME_FORTEZZA, SEC_OID_FORTEZZA_SKIPJACK, NULL, PR_TRUE, PR_TRUE } -}; -static const int smime_cipher_map_count = sizeof(smime_cipher_map) / sizeof(smime_cipher_map_entry); - -/* - * smime_mapi_by_cipher - find index into smime_cipher_map by cipher - */ -static int -smime_mapi_by_cipher(unsigned long cipher) -{ - int i; - - for (i = 0; i < smime_cipher_map_count; i++) { - if (smime_cipher_map[i].cipher == cipher) - return i; /* bingo */ - } - return -1; /* should not happen if we're consistent, right? */ -} - -/* - * NSS_SMIME_EnableCipher - this function locally records the user's preference - */ -SECStatus -NSS_SMIMEUtil_EnableCipher(unsigned long which, PRBool on) -{ - unsigned long mask; - int mapi; - - mask = which & CIPHER_FAMILYID_MASK; - - PORT_Assert (mask == CIPHER_FAMILYID_SMIME); - if (mask != CIPHER_FAMILYID_SMIME) - /* XXX set an error! */ - return SECFailure; - - mapi = smime_mapi_by_cipher(which); - if (mapi < 0) - /* XXX set an error */ - return SECFailure; - - /* do we try to turn on a forbidden cipher? */ - if (!smime_cipher_map[mapi].allowed && on) { - PORT_SetError (SEC_ERROR_BAD_EXPORT_ALGORITHM); - return SECFailure; - } - - if (smime_cipher_map[mapi].enabled != on) - smime_cipher_map[mapi].enabled = on; - - return SECSuccess; -} - - -/* - * this function locally records the export policy - */ -SECStatus -NSS_SMIMEUtil_AllowCipher(unsigned long which, PRBool on) -{ - unsigned long mask; - int mapi; - - mask = which & CIPHER_FAMILYID_MASK; - - PORT_Assert (mask == CIPHER_FAMILYID_SMIME); - if (mask != CIPHER_FAMILYID_SMIME) - /* XXX set an error! */ - return SECFailure; - - mapi = smime_mapi_by_cipher(which); - if (mapi < 0) - /* XXX set an error */ - return SECFailure; - - if (smime_cipher_map[mapi].allowed != on) - smime_cipher_map[mapi].allowed = on; - - return SECSuccess; -} - -/* - * Based on the given algorithm (including its parameters, in some cases!) - * and the given key (may or may not be inspected, depending on the - * algorithm), find the appropriate policy algorithm specification - * and return it. If no match can be made, -1 is returned. - */ -static SECStatus -nss_smime_get_cipher_for_alg_and_key(SECAlgorithmID *algid, PK11SymKey *key, unsigned long *cipher) -{ - SECOidTag algtag; - unsigned int keylen_bits; - unsigned long c; - - algtag = SECOID_GetAlgorithmTag(algid); - switch (algtag) { - case SEC_OID_RC2_CBC: - keylen_bits = PK11_GetKeyStrength(key, algid); - switch (keylen_bits) { - case 40: - c = SMIME_RC2_CBC_40; - break; - case 64: - c = SMIME_RC2_CBC_64; - break; - case 128: - c = SMIME_RC2_CBC_128; - break; - default: - return SECFailure; - } - break; - case SEC_OID_DES_CBC: - c = SMIME_DES_CBC_56; - break; - case SEC_OID_DES_EDE3_CBC: - c = SMIME_DES_EDE3_168; - break; - case SEC_OID_FORTEZZA_SKIPJACK: - c = SMIME_FORTEZZA; - break; - default: - return SECFailure; - } - *cipher = c; - return SECSuccess; -} - -static PRBool -nss_smime_cipher_allowed(unsigned long which) -{ - int mapi; - - mapi = smime_mapi_by_cipher(which); - if (mapi < 0) - return PR_FALSE; - return smime_cipher_map[mapi].allowed; -} - -PRBool -NSS_SMIMEUtil_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key) -{ - unsigned long which; - - if (nss_smime_get_cipher_for_alg_and_key(algid, key, &which) != SECSuccess) - return PR_FALSE; - - return nss_smime_cipher_allowed(which); -} - - -/* - * NSS_SMIME_EncryptionPossible - check if any encryption is allowed - * - * This tells whether or not *any* S/MIME encryption can be done, - * according to policy. Callers may use this to do nicer user interface - * (say, greying out a checkbox so a user does not even try to encrypt - * a message when they are not allowed to) or for any reason they want - * to check whether S/MIME encryption (or decryption, for that matter) - * may be done. - * - * It takes no arguments. The return value is a simple boolean: - * PR_TRUE means encryption (or decryption) is *possible* - * (but may still fail due to other reasons, like because we cannot - * find all the necessary certs, etc.; PR_TRUE is *not* a guarantee) - * PR_FALSE means encryption (or decryption) is not permitted - * - * There are no errors from this routine. - */ -PRBool -NSS_SMIMEUtil_EncryptionPossible(void) -{ - int i; - - for (i = 0; i < smime_cipher_map_count; i++) { - if (smime_cipher_map[i].allowed) - return PR_TRUE; - } - return PR_FALSE; -} - - -static int -nss_SMIME_FindCipherForSMIMECap(NSSSMIMECapability *cap) -{ - int i; - SECOidTag capIDTag; - - /* we need the OIDTag here */ - capIDTag = SECOID_FindOIDTag(&(cap->capabilityID)); - - /* go over all the SMIME ciphers we know and see if we find a match */ - for (i = 0; i < smime_cipher_map_count; i++) { - if (smime_cipher_map[i].algtag != capIDTag) - continue; - /* - * XXX If SECITEM_CompareItem allowed NULLs as arguments (comparing - * 2 NULLs as equal and NULL and non-NULL as not equal), we could - * use that here instead of all of the following comparison code. - */ - if (cap->parameters.data == NULL && smime_cipher_map[i].parms == NULL) - break; /* both empty: bingo */ - - if (cap->parameters.data != NULL && smime_cipher_map[i].parms != NULL && - cap->parameters.len == smime_cipher_map[i].parms->len && - PORT_Memcmp (cap->parameters.data, smime_cipher_map[i].parms->data, - cap->parameters.len) == 0) - { - break; /* both not empty, same length & equal content: bingo */ - } - } - - if (i == smime_cipher_map_count) - return 0; /* no match found */ - else - return smime_cipher_map[i].cipher; /* match found, point to cipher */ -} - -/* - * smime_choose_cipher - choose a cipher that works for all the recipients - * - * "scert" - sender's certificate - * "rcerts" - recipient's certificates - */ -static long -smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts) -{ - PRArenaPool *poolp; - long cipher; - long chosen_cipher; - int *cipher_abilities; - int *cipher_votes; - int weak_mapi; - int strong_mapi; - int rcount, mapi, max, i; - PRBool scert_is_fortezza = (scert == NULL) ? PR_FALSE : PK11_FortezzaHasKEA(scert); - - chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */ - weak_mapi = smime_mapi_by_cipher(chosen_cipher); - - poolp = PORT_NewArena (1024); /* XXX what is right value? */ - if (poolp == NULL) - goto done; - - cipher_abilities = (int *)PORT_ArenaZAlloc(poolp, smime_cipher_map_count * sizeof(int)); - cipher_votes = (int *)PORT_ArenaZAlloc(poolp, smime_cipher_map_count * sizeof(int)); - if (cipher_votes == NULL || cipher_abilities == NULL) - goto done; - - /* If the user has the Fortezza preference turned on, make - * that the strong cipher. Otherwise, use triple-DES. */ - strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168); - if (scert_is_fortezza) { - mapi = smime_mapi_by_cipher(SMIME_FORTEZZA); - if (mapi >= 0 && smime_cipher_map[mapi].enabled) - strong_mapi = mapi; - } - - /* walk all the recipient's certs */ - for (rcount = 0; rcerts[rcount] != NULL; rcount++) { - SECItem *profile; - NSSSMIMECapability **caps; - int pref; - - /* the first cipher that matches in the user's SMIME profile gets - * "smime_cipher_map_count" votes; the next one gets "smime_cipher_map_count" - 1 - * and so on. If every cipher matches, the last one gets 1 (one) vote */ - pref = smime_cipher_map_count; - - /* find recipient's SMIME profile */ - profile = CERT_FindSMimeProfile(rcerts[rcount]); - - if (profile != NULL && profile->data != NULL && profile->len > 0) { - /* we have a profile (still DER-encoded) */ - caps = NULL; - /* decode it */ - if (SEC_QuickDERDecodeItem(poolp, &caps, - NSSSMIMECapabilitiesTemplate, profile) == SECSuccess && - caps != NULL) - { - /* walk the SMIME capabilities for this recipient */ - for (i = 0; caps[i] != NULL; i++) { - cipher = nss_SMIME_FindCipherForSMIMECap(caps[i]); - mapi = smime_mapi_by_cipher(cipher); - if (mapi >= 0) { - /* found the cipher */ - cipher_abilities[mapi]++; - cipher_votes[mapi] += pref; - --pref; - } - } - } - } else { - /* no profile found - so we can only assume that the user can do - * the mandatory algorithms which is RC2-40 (weak crypto) and 3DES (strong crypto) */ - SECKEYPublicKey *key; - unsigned int pklen_bits; - - /* - * if recipient's public key length is > 512, vote for a strong cipher - * please not that the side effect of this is that if only one recipient - * has an export-level public key, the strong cipher is disabled. - * - * XXX This is probably only good for RSA keys. What I would - * really like is a function to just say; Is the public key in - * this cert an export-length key? Then I would not have to - * know things like the value 512, or the kind of key, or what - * a subjectPublicKeyInfo is, etc. - */ - key = CERT_ExtractPublicKey(rcerts[rcount]); - pklen_bits = 0; - if (key != NULL) { - pklen_bits = SECKEY_PublicKeyStrength (key) * 8; - SECKEY_DestroyPublicKey (key); - } - - if (pklen_bits > 512) { - /* cast votes for the strong algorithm */ - cipher_abilities[strong_mapi]++; - cipher_votes[strong_mapi] += pref; - pref--; - } - - /* always cast (possibly less) votes for the weak algorithm */ - cipher_abilities[weak_mapi]++; - cipher_votes[weak_mapi] += pref; - } - if (profile != NULL) - SECITEM_FreeItem(profile, PR_TRUE); - } - - /* find cipher that is agreeable by all recipients and that has the most votes */ - max = 0; - for (mapi = 0; mapi < smime_cipher_map_count; mapi++) { - /* if not all of the recipients can do this, forget it */ - if (cipher_abilities[mapi] != rcount) - continue; - /* if cipher is not enabled or not allowed by policy, forget it */ - if (!smime_cipher_map[mapi].enabled || !smime_cipher_map[mapi].allowed) - continue; - /* if we're not doing fortezza, but the cipher is fortezza, forget it */ - if (!scert_is_fortezza && (smime_cipher_map[mapi].cipher == SMIME_FORTEZZA)) - continue; - /* now see if this one has more votes than the last best one */ - if (cipher_votes[mapi] >= max) { - /* if equal number of votes, prefer the ones further down in the list */ - /* with the expectation that these are higher rated ciphers */ - chosen_cipher = smime_cipher_map[mapi].cipher; - max = cipher_votes[mapi]; - } - } - /* if no common cipher was found, chosen_cipher stays at the default */ - -done: - if (poolp != NULL) - PORT_FreeArena (poolp, PR_FALSE); - - return chosen_cipher; -} - -/* - * XXX This is a hack for now to satisfy our current interface. - * Eventually, with more parameters needing to be specified, just - * looking up the keysize is not going to be sufficient. - */ -static int -smime_keysize_by_cipher (unsigned long which) -{ - int keysize; - - switch (which) { - case SMIME_RC2_CBC_40: - keysize = 40; - break; - case SMIME_RC2_CBC_64: - keysize = 64; - break; - case SMIME_RC2_CBC_128: - keysize = 128; - break; - case SMIME_DES_CBC_56: - case SMIME_DES_EDE3_168: - case SMIME_FORTEZZA: - /* - * These are special; since the key size is fixed, we actually - * want to *avoid* specifying a key size. - */ - keysize = 0; - break; - default: - keysize = -1; - break; - } - - return keysize; -} - -/* - * NSS_SMIMEUtil_FindBulkAlgForRecipients - find bulk algorithm suitable for all recipients - * - * it would be great for UI purposes if there would be a way to find out which recipients - * prevented a strong cipher from being used... - */ -SECStatus -NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts, SECOidTag *bulkalgtag, int *keysize) -{ - unsigned long cipher; - int mapi; - - cipher = smime_choose_cipher(NULL, rcerts); - mapi = smime_mapi_by_cipher(cipher); - - *bulkalgtag = smime_cipher_map[mapi].algtag; - *keysize = smime_keysize_by_cipher(smime_cipher_map[mapi].cipher); - - return SECSuccess; -} - -/* - * NSS_SMIMEUtil_CreateSMIMECapabilities - get S/MIME capabilities for this instance of NSS - * - * scans the list of allowed and enabled ciphers and construct a PKCS9-compliant - * S/MIME capabilities attribute value. - * - * XXX Please note that, in contradiction to RFC2633 2.5.2, the capabilities only include - * symmetric ciphers, NO signature algorithms or key encipherment algorithms. - * - * "poolp" - arena pool to create the S/MIME capabilities data on - * "dest" - SECItem to put the data in - * "includeFortezzaCiphers" - PR_TRUE if fortezza ciphers should be included - */ -SECStatus -NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool includeFortezzaCiphers) -{ - NSSSMIMECapability *cap; - NSSSMIMECapability **smime_capabilities; - smime_cipher_map_entry *map; - SECOidData *oiddata; - SECItem *dummy; - int i, capIndex; - - /* if we have an old NSSSMIMECapability array, we'll reuse it (has the right size) */ - /* smime_cipher_map_count + 1 is an upper bound - we might end up with less */ - smime_capabilities = (NSSSMIMECapability **)PORT_ZAlloc((smime_cipher_map_count + 1) - * sizeof(NSSSMIMECapability *)); - if (smime_capabilities == NULL) - return SECFailure; - - capIndex = 0; - - /* Add all the symmetric ciphers - * We walk the cipher list backwards, as it is ordered by increasing strength, - * we prefer the stronger cipher over a weaker one, and we have to list the - * preferred algorithm first */ - for (i = smime_cipher_map_count - 1; i >= 0; i--) { - /* Find the corresponding entry in the cipher map. */ - map = &(smime_cipher_map[i]); - if (!map->enabled) - continue; - - /* If we're using a non-Fortezza cert, only advertise non-Fortezza - capabilities. (We advertise all capabilities if we have a - Fortezza cert.) */ - if ((!includeFortezzaCiphers) && (map->cipher == SMIME_FORTEZZA)) - continue; - - /* get next SMIME capability */ - cap = (NSSSMIMECapability *)PORT_ZAlloc(sizeof(NSSSMIMECapability)); - if (cap == NULL) - break; - smime_capabilities[capIndex++] = cap; - - oiddata = SECOID_FindOIDByTag(map->algtag); - if (oiddata == NULL) - break; - - cap->capabilityID.data = oiddata->oid.data; - cap->capabilityID.len = oiddata->oid.len; - cap->parameters.data = map->parms ? map->parms->data : NULL; - cap->parameters.len = map->parms ? map->parms->len : 0; - cap->cipher = smime_cipher_map[i].cipher; - } - - /* XXX add signature algorithms */ - /* XXX add key encipherment algorithms */ - - smime_capabilities[capIndex] = NULL; /* last one - now encode */ - dummy = SEC_ASN1EncodeItem(poolp, dest, &smime_capabilities, NSSSMIMECapabilitiesTemplate); - - /* now that we have the proper encoded SMIMECapabilities (or not), - * free the work data */ - for (i = 0; smime_capabilities[i] != NULL; i++) - PORT_Free(smime_capabilities[i]); - PORT_Free(smime_capabilities); - - return (dummy == NULL) ? SECFailure : SECSuccess; -} - -/* - * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value - * - * "poolp" - arena pool to create the attr value on - * "dest" - SECItem to put the data in - * "cert" - certificate that should be marked as preferred encryption key - * cert is expected to have been verified for EmailRecipient usage. - */ -SECStatus -NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert) -{ - NSSSMIMEEncryptionKeyPreference ekp; - SECItem *dummy = NULL; - PLArenaPool *tmppoolp = NULL; - - if (cert == NULL) - goto loser; - - tmppoolp = PORT_NewArena(1024); - if (tmppoolp == NULL) - goto loser; - - /* XXX hardcoded IssuerSN choice for now */ - ekp.selector = NSSSMIMEEncryptionKeyPref_IssuerSN; - ekp.id.issuerAndSN = CERT_GetCertIssuerAndSN(tmppoolp, cert); - if (ekp.id.issuerAndSN == NULL) - goto loser; - - dummy = SEC_ASN1EncodeItem(poolp, dest, &ekp, smime_encryptionkeypref_template); - -loser: - if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE); - - return (dummy == NULL) ? SECFailure : SECSuccess; -} - -/* - * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value using MS oid - * - * "poolp" - arena pool to create the attr value on - * "dest" - SECItem to put the data in - * "cert" - certificate that should be marked as preferred encryption key - * cert is expected to have been verified for EmailRecipient usage. - */ -SECStatus -NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert) -{ - SECItem *dummy = NULL; - PLArenaPool *tmppoolp = NULL; - CERTIssuerAndSN *isn; - - if (cert == NULL) - goto loser; - - tmppoolp = PORT_NewArena(1024); - if (tmppoolp == NULL) - goto loser; - - isn = CERT_GetCertIssuerAndSN(tmppoolp, cert); - if (isn == NULL) - goto loser; - - dummy = SEC_ASN1EncodeItem(poolp, dest, isn, SEC_ASN1_GET(CERT_IssuerAndSNTemplate)); - -loser: - if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE); - - return (dummy == NULL) ? SECFailure : SECSuccess; -} - -/* - * NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference - - * find cert marked by EncryptionKeyPreference attribute - * - * "certdb" - handle for the cert database to look in - * "DERekp" - DER-encoded value of S/MIME Encryption Key Preference attribute - * - * if certificate is supposed to be found among the message's included certificates, - * they are assumed to have been imported already. - */ -CERTCertificate * -NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(CERTCertDBHandle *certdb, SECItem *DERekp) -{ - PLArenaPool *tmppoolp = NULL; - CERTCertificate *cert = NULL; - NSSSMIMEEncryptionKeyPreference ekp; - - tmppoolp = PORT_NewArena(1024); - if (tmppoolp == NULL) - return NULL; - - /* decode DERekp */ - if (SEC_QuickDERDecodeItem(tmppoolp, &ekp, smime_encryptionkeypref_template, - DERekp) != SECSuccess) - goto loser; - - /* find cert */ - switch (ekp.selector) { - case NSSSMIMEEncryptionKeyPref_IssuerSN: - cert = CERT_FindCertByIssuerAndSN(certdb, ekp.id.issuerAndSN); - break; - case NSSSMIMEEncryptionKeyPref_RKeyID: - case NSSSMIMEEncryptionKeyPref_SubjectKeyID: - /* XXX not supported yet - we need to be able to look up certs by SubjectKeyID */ - break; - default: - PORT_Assert(0); - } -loser: - if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE); - - return cert; -} - -extern const char __nss_smime_rcsid[]; -extern const char __nss_smime_sccsid[]; - -PRBool -NSSSMIME_VersionCheck(const char *importedVersion) -{ - /* - * This is the secret handshake algorithm. - * - * This release has a simple version compatibility - * check algorithm. This release is not backward - * compatible with previous major releases. It is - * not compatible with future major, minor, or - * patch releases. - */ - volatile char c; /* force a reference that won't get optimized away */ - - c = __nss_smime_rcsid[0] + __nss_smime_sccsid[0]; - - return NSS_VersionCheck(importedVersion); -} - diff --git a/security/nss/lib/smime/smimever.c b/security/nss/lib/smime/smimever.c deleted file mode 100644 index df838e30a..000000000 --- a/security/nss/lib/smime/smimever.c +++ /dev/null @@ -1,56 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* Library identity and versioning */ - -#include "nss.h" - -#if defined(DEBUG) -#define _DEBUG_STRING " (debug)" -#else -#define _DEBUG_STRING "" -#endif - -/* - * Version information for the 'ident' and 'what commands - * - * NOTE: the first component of the concatenated rcsid string - * must not end in a '$' to prevent rcs keyword substitution. - */ -const char __nss_smime_rcsid[] = "$Header: NSS " NSS_VERSION _DEBUG_STRING - " " __DATE__ " " __TIME__ " $"; -const char __nss_smime_sccsid[] = "@(#)NSS " NSS_VERSION _DEBUG_STRING - " " __DATE__ " " __TIME__; |