security/nss/lib/smime/smimemessage.c

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * SMIME message methods
     7  */
     9 #include "cmslocal.h"
    10 #include "smime.h"
    12 #include "cert.h"
    13 #include "key.h"
    14 #include "secasn1.h"
    15 #include "secitem.h"
    16 #include "secoid.h"
    17 #include "pk11func.h"
    18 #include "prtime.h"
    19 #include "secerr.h"
    22 #if 0
    23 /*
    24  * NSS_SMIMEMessage_CreateEncrypted - start an S/MIME encrypting context.
    25  *
    26  * "scert" is the cert for the sender.  It will be checked for validity.
    27  * "rcerts" are the certs for the recipients.  They will also be checked.
    28  *
    29  * "certdb" is the cert database to use for verifying the certs.
    30  * It can be NULL if a default database is available (like in the client).
    31  *
    32  * This function already does all of the stuff specific to S/MIME protocol
    33  * and local policy; the return value just needs to be passed to
    34  * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
    35  * and finally to SEC_PKCS7DestroyContentInfo().
    36  *
    37  * An error results in a return value of NULL and an error set.
    38  * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
    39  */
    40 NSSCMSMessage *
    41 NSS_SMIMEMessage_CreateEncrypted(CERTCertificate *scert,
    42 			CERTCertificate **rcerts,
    43 			CERTCertDBHandle *certdb,
    44 			PK11PasswordFunc pwfn,
    45 			void *pwfn_arg)
    46 {
    47     NSSCMSMessage *cmsg;
    48     long cipher;
    49     SECOidTag encalg;
    50     int keysize;
    51     int mapi, rci;
    53     cipher = smime_choose_cipher (scert, rcerts);
    54     if (cipher < 0)
    55 	return NULL;
    57     mapi = smime_mapi_by_cipher (cipher);
    58     if (mapi < 0)
    59 	return NULL;
    61     /*
    62      * XXX This is stretching it -- CreateEnvelopedData should probably
    63      * take a cipher itself of some sort, because we cannot know what the
    64      * future will bring in terms of parameters for each type of algorithm.
    65      * For example, just an algorithm and keysize is *not* sufficient to
    66      * fully specify the usage of RC5 (which also needs to know rounds and
    67      * block size).  Work this out into a better API!
    68      */
    69     encalg = smime_cipher_map[mapi].algtag;
    70     keysize = smime_keysize_by_cipher (cipher);
    71     if (keysize < 0)
    72 	return NULL;
    74     cinfo = SEC_PKCS7CreateEnvelopedData (scert, certUsageEmailRecipient,
    75 					  certdb, encalg, keysize,
    76 					  pwfn, pwfn_arg);
    77     if (cinfo == NULL)
    78 	return NULL;
    80     for (rci = 0; rcerts[rci] != NULL; rci++) {
    81 	if (rcerts[rci] == scert)
    82 	    continue;
    83 	if (SEC_PKCS7AddRecipient (cinfo, rcerts[rci], certUsageEmailRecipient,
    84 				   NULL) != SECSuccess) {
    85 	    SEC_PKCS7DestroyContentInfo (cinfo);
    86 	    return NULL;
    87 	}
    88     }
    90     return cinfo;
    91 }
    94 /*
    95  * Start an S/MIME signing context.
    96  *
    97  * "scert" is the cert that will be used to sign the data.  It will be
    98  * checked for validity.
    99  *
   100  * "ecert" is the signer's encryption cert.  If it is different from
   101  * scert, then it will be included in the signed message so that the
   102  * recipient can save it for future encryptions.
   103  *
   104  * "certdb" is the cert database to use for verifying the cert.
   105  * It can be NULL if a default database is available (like in the client).
   106  * 
   107  * "digestalg" names the digest algorithm (e.g. SEC_OID_SHA1).
   108  * XXX There should be SECMIME functions for hashing, or the hashing should
   109  * be built into this interface, which we would like because we would
   110  * support more smartcards that way, and then this argument should go away.)
   111  *
   112  * "digest" is the actual digest of the data.  It must be provided in
   113  * the case of detached data or NULL if the content will be included.
   114  *
   115  * This function already does all of the stuff specific to S/MIME protocol
   116  * and local policy; the return value just needs to be passed to
   117  * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
   118  * and finally to SEC_PKCS7DestroyContentInfo().
   119  *
   120  * An error results in a return value of NULL and an error set.
   121  * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
   122  */
   124 NSSCMSMessage *
   125 NSS_SMIMEMessage_CreateSigned(CERTCertificate *scert,
   126 		      CERTCertificate *ecert,
   127 		      CERTCertDBHandle *certdb,
   128 		      SECOidTag digestalgtag,
   129 		      SECItem *digest,
   130 		      PK11PasswordFunc pwfn,
   131 		      void *pwfn_arg)
   132 {
   133     NSSCMSMessage *cmsg;
   134     NSSCMSSignedData *sigd;
   135     NSSCMSSignerInfo *signerinfo;
   137     /* See note in header comment above about digestalg. */
   138     /* Doesn't explain this.  PORT_Assert (digestalgtag == SEC_OID_SHA1); */
   140     cmsg = NSS_CMSMessage_Create(NULL);
   141     if (cmsg == NULL)
   142 	return NULL;
   144     sigd = NSS_CMSSignedData_Create(cmsg);
   145     if (sigd == NULL)
   146 	goto loser;
   148     /* create just one signerinfo */
   149     signerinfo = NSS_CMSSignerInfo_Create(cmsg, scert, digestalgtag);
   150     if (signerinfo == NULL)
   151 	goto loser;
   153     /* Add the signing time to the signerinfo.  */
   154     if (NSS_CMSSignerInfo_AddSigningTime(signerinfo, PR_Now()) != SECSuccess)
   155 	goto loser;
   157     /* and add the SMIME profile */
   158     if (NSS_SMIMESignerInfo_AddSMIMEProfile(signerinfo, scert) != SECSuccess)
   159 	goto loser;
   161     /* now add the signerinfo to the signeddata */
   162     if (NSS_CMSSignedData_AddSignerInfo(sigd, signerinfo) != SECSuccess)
   163 	goto loser;
   165     /* include the signing cert and its entire chain */
   166     /* note that there are no checks for duplicate certs in place, as all the */
   167     /* essential data structures (like set of certificate) are not there */
   168     if (NSS_CMSSignedData_AddCertChain(sigd, scert) != SECSuccess)
   169 	goto loser;
   171     /* If the encryption cert and the signing cert differ, then include
   172      * the encryption cert too. */
   173     if ( ( ecert != NULL ) && ( ecert != scert ) ) {
   174 	if (NSS_CMSSignedData_AddCertificate(sigd, ecert) != SECSuccess)
   175 	    goto loser;
   176     }
   178     return cmsg;
   179 loser:
   180     if (cmsg)
   181 	NSS_CMSMessage_Destroy(cmsg);
   182     return NULL;
   183 }
   184 #endif

mercurial