cmsreclist.c (6122B)
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/. */ 4 5 /* 6 * CMS recipient list functions 7 */ 8 9 #include "cmslocal.h" 10 11 #include "cert.h" 12 #include "keyhi.h" 13 #include "secasn1.h" 14 #include "secitem.h" 15 #include "secoid.h" 16 #include "pk11func.h" 17 #include "prtime.h" 18 #include "secerr.h" 19 20 static int 21 nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, 22 NSSCMSRecipient **recipient_list) 23 { 24 int count = 0; 25 int rlindex = 0; 26 int i, j; 27 NSSCMSRecipient *rle; 28 NSSCMSRecipientInfo *ri; 29 NSSCMSRecipientEncryptedKey *rek; 30 31 for (i = 0; recipientinfos[i] != NULL; i++) { 32 ri = recipientinfos[i]; 33 switch (ri->recipientInfoType) { 34 case NSSCMSRecipientInfoID_KeyTrans: 35 if (recipient_list) { 36 NSSCMSRecipientIdentifier *recipId = 37 &ri->ri.keyTransRecipientInfo.recipientIdentifier; 38 39 if (recipId->identifierType != NSSCMSRecipientID_IssuerSN && 40 recipId->identifierType != NSSCMSRecipientID_SubjectKeyID) { 41 PORT_SetError(SEC_ERROR_INVALID_ARGS); 42 return -1; 43 } 44 /* alloc one & fill it out */ 45 rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient)); 46 if (!rle) 47 return -1; 48 49 rle->riIndex = i; 50 rle->subIndex = -1; 51 switch (recipId->identifierType) { 52 case NSSCMSRecipientID_IssuerSN: 53 rle->kind = RLIssuerSN; 54 rle->id.issuerAndSN = recipId->id.issuerAndSN; 55 break; 56 case NSSCMSRecipientID_SubjectKeyID: 57 rle->kind = RLSubjKeyID; 58 rle->id.subjectKeyID = recipId->id.subjectKeyID; 59 break; 60 default: /* we never get here because of identifierType check 61 we done before. Leaving it to kill compiler warning */ 62 break; 63 } 64 recipient_list[rlindex++] = rle; 65 } else { 66 count++; 67 } 68 break; 69 case NSSCMSRecipientInfoID_KeyAgree: 70 if (ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys == NULL) 71 break; 72 for (j = 0; ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j] != NULL; j++) { 73 if (recipient_list) { 74 rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j]; 75 /* alloc one & fill it out */ 76 rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient)); 77 if (!rle) 78 return -1; 79 80 rle->riIndex = i; 81 rle->subIndex = j; 82 switch (rek->recipientIdentifier.identifierType) { 83 case NSSCMSKeyAgreeRecipientID_IssuerSN: 84 rle->kind = RLIssuerSN; 85 rle->id.issuerAndSN = rek->recipientIdentifier.id.issuerAndSN; 86 break; 87 case NSSCMSKeyAgreeRecipientID_RKeyID: 88 rle->kind = RLSubjKeyID; 89 rle->id.subjectKeyID = 90 rek->recipientIdentifier.id.recipientKeyIdentifier.subjectKeyIdentifier; 91 break; 92 } 93 recipient_list[rlindex++] = rle; 94 } else { 95 count++; 96 } 97 } 98 break; 99 case NSSCMSRecipientInfoID_KEK: 100 /* KEK is not implemented */ 101 break; 102 } 103 } 104 /* if we have a recipient list, we return on success (-1, above, on failure) */ 105 /* otherwise, we return the count. */ 106 if (recipient_list) { 107 recipient_list[rlindex] = NULL; 108 return 0; 109 } else { 110 return count; 111 } 112 } 113 114 NSSCMSRecipient ** 115 nss_cms_recipient_list_create(NSSCMSRecipientInfo **recipientinfos) 116 { 117 int count, rv; 118 NSSCMSRecipient **recipient_list; 119 120 /* count the number of recipient identifiers */ 121 count = nss_cms_recipients_traverse(recipientinfos, NULL); 122 if (count <= 0) { 123 /* no recipients? */ 124 PORT_SetError(SEC_ERROR_BAD_DATA); 125 #if 0 126 PORT_SetErrorString("Cannot find recipient data in envelope."); 127 #endif 128 return NULL; 129 } 130 131 /* allocate an array of pointers */ 132 recipient_list = (NSSCMSRecipient **) 133 PORT_ZAlloc((count + 1) * sizeof(NSSCMSRecipient *)); 134 if (recipient_list == NULL) 135 return NULL; 136 137 /* now fill in the recipient_list */ 138 rv = nss_cms_recipients_traverse(recipientinfos, recipient_list); 139 if (rv < 0) { 140 nss_cms_recipient_list_destroy(recipient_list); 141 return NULL; 142 } 143 return recipient_list; 144 } 145 146 void 147 nss_cms_recipient_list_destroy(NSSCMSRecipient **recipient_list) 148 { 149 int i; 150 NSSCMSRecipient *recipient; 151 152 for (i = 0; recipient_list[i] != NULL; i++) { 153 recipient = recipient_list[i]; 154 if (recipient->cert) 155 CERT_DestroyCertificate(recipient->cert); 156 if (recipient->privkey) 157 SECKEY_DestroyPrivateKey(recipient->privkey); 158 if (recipient->slot) 159 PK11_FreeSlot(recipient->slot); 160 PORT_Free(recipient); 161 } 162 PORT_Free(recipient_list); 163 } 164 165 NSSCMSRecipientEncryptedKey * 166 NSS_CMSRecipientEncryptedKey_Create(PLArenaPool *poolp) 167 { 168 return (NSSCMSRecipientEncryptedKey *)PORT_ArenaZAlloc(poolp, 169 sizeof(NSSCMSRecipientEncryptedKey)); 170 }