Back to index

lightning-sunbird  0.9+nobinonly
cmsreclist.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 /*
00038  * CMS recipient list functions
00039  *
00040  * $Id: cmsreclist.c,v 1.4.2.1 2006/07/17 21:57:12 alexei.volkov.bugs%sun.com Exp $
00041  */
00042 
00043 #include "cmslocal.h"
00044 
00045 #include "cert.h"
00046 #include "key.h"
00047 #include "secasn1.h"
00048 #include "secitem.h"
00049 #include "secoid.h"
00050 #include "pk11func.h"
00051 #include "prtime.h"
00052 #include "secerr.h"
00053 
00054 static int
00055 nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, NSSCMSRecipient **recipient_list)
00056 {
00057     int count = 0;
00058     int rlindex = 0;
00059     int i, j;
00060     NSSCMSRecipient *rle;
00061     NSSCMSRecipientInfo *ri;
00062     NSSCMSRecipientEncryptedKey *rek;
00063 
00064     for (i = 0; recipientinfos[i] != NULL; i++) {
00065        ri = recipientinfos[i];
00066        switch (ri->recipientInfoType) {
00067        case NSSCMSRecipientInfoID_KeyTrans:
00068            if (recipient_list) {
00069               NSSCMSRecipientIdentifier *recipId =
00070                  &ri->ri.keyTransRecipientInfo.recipientIdentifier;
00071 
00072               if (recipId->identifierType != NSSCMSRecipientID_IssuerSN &&
00073                     recipId->identifierType != NSSCMSRecipientID_SubjectKeyID) {
00074                   PORT_SetError(SEC_ERROR_INVALID_ARGS);
00075                   return -1;
00076               }                
00077               /* alloc one & fill it out */
00078               rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
00079               if (!rle)
00080                   return -1;
00081               
00082               rle->riIndex = i;
00083               rle->subIndex = -1;
00084               switch (recipId->identifierType) {
00085               case NSSCMSRecipientID_IssuerSN:
00086                   rle->kind = RLIssuerSN;
00087                   rle->id.issuerAndSN = recipId->id.issuerAndSN;
00088                   break;
00089               case NSSCMSRecipientID_SubjectKeyID:
00090                   rle->kind = RLSubjKeyID;
00091                   rle->id.subjectKeyID = recipId->id.subjectKeyID;
00092                   break;
00093               default: /* we never get here because of identifierType check
00094                             we done before. Leaving it to kill compiler warning */
00095                   break;
00096               }
00097               recipient_list[rlindex++] = rle;
00098            } else {
00099               count++;
00100            }
00101            break;
00102        case NSSCMSRecipientInfoID_KeyAgree:
00103            if (ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys == NULL)
00104               break;
00105            for (j=0; ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j] != NULL; j++) {
00106               if (recipient_list) {
00107                   rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j];
00108                   /* alloc one & fill it out */
00109                   rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
00110                   if (!rle)
00111                      return -1;
00112                   
00113                   rle->riIndex = i;
00114                   rle->subIndex = j;
00115                   switch (rek->recipientIdentifier.identifierType) {
00116                   case NSSCMSKeyAgreeRecipientID_IssuerSN:
00117                      rle->kind = RLIssuerSN;
00118                      rle->id.issuerAndSN = rek->recipientIdentifier.id.issuerAndSN;
00119                      break;
00120                   case NSSCMSKeyAgreeRecipientID_RKeyID:
00121                      rle->kind = RLSubjKeyID;
00122                      rle->id.subjectKeyID = rek->recipientIdentifier.id.recipientKeyIdentifier.subjectKeyIdentifier;
00123                      break;
00124                   }
00125                   recipient_list[rlindex++] = rle;
00126               } else {
00127                   count++;
00128               }
00129            }
00130            break;
00131        case NSSCMSRecipientInfoID_KEK:
00132            /* KEK is not implemented */
00133            break;
00134        }
00135     }
00136     /* if we have a recipient list, we return on success (-1, above, on failure) */
00137     /* otherwise, we return the count. */
00138     if (recipient_list) {
00139        recipient_list[rlindex] = NULL;
00140        return 0;
00141     } else {
00142        return count;
00143     }
00144 }
00145 
00146 NSSCMSRecipient **
00147 nss_cms_recipient_list_create(NSSCMSRecipientInfo **recipientinfos)
00148 {
00149     int count, rv;
00150     NSSCMSRecipient **recipient_list;
00151 
00152     /* count the number of recipient identifiers */
00153     count = nss_cms_recipients_traverse(recipientinfos, NULL);
00154     if (count <= 0) {
00155        /* no recipients? */
00156        PORT_SetError(SEC_ERROR_BAD_DATA);
00157 #if 0
00158        PORT_SetErrorString("Cannot find recipient data in envelope.");
00159 #endif
00160        return NULL;
00161     }
00162 
00163     /* allocate an array of pointers */
00164     recipient_list = (NSSCMSRecipient **)
00165                   PORT_ZAlloc((count + 1) * sizeof(NSSCMSRecipient *));
00166     if (recipient_list == NULL)
00167        return NULL;
00168 
00169     /* now fill in the recipient_list */
00170     rv = nss_cms_recipients_traverse(recipientinfos, recipient_list);
00171     if (rv < 0) {
00172        nss_cms_recipient_list_destroy(recipient_list);
00173        return NULL;
00174     }
00175     return recipient_list;
00176 }
00177 
00178 void
00179 nss_cms_recipient_list_destroy(NSSCMSRecipient **recipient_list)
00180 {
00181     int i;
00182     NSSCMSRecipient *recipient;
00183 
00184     for (i=0; recipient_list[i] != NULL; i++) {
00185        recipient = recipient_list[i];
00186        if (recipient->cert)
00187            CERT_DestroyCertificate(recipient->cert);
00188        if (recipient->privkey)
00189            SECKEY_DestroyPrivateKey(recipient->privkey);
00190        if (recipient->slot)
00191            PK11_FreeSlot(recipient->slot);
00192        PORT_Free(recipient);
00193     }
00194     PORT_Free(recipient_list);
00195 }
00196 
00197 NSSCMSRecipientEncryptedKey *
00198 NSS_CMSRecipientEncryptedKey_Create(PLArenaPool *poolp)
00199 {
00200     return (NSSCMSRecipientEncryptedKey *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSRecipientEncryptedKey));
00201 }