1/* 2 * Copyright (c) 2003-2004,2008,2010 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * pkcs12Templates.cpp 25 */ 26 27#include <stddef.h> 28#include "pkcs12Templates.h" 29#include "nssUtils.h" 30#include "SecAsn1Templates.h" 31#include "oidsattr.h" 32 33const SecAsn1Template NSS_P12_MacDataTemplate[] = { 34 { SEC_ASN1_SEQUENCE, 35 0, NULL, sizeof(NSS_P12_MacData) }, 36 { SEC_ASN1_INLINE, 37 offsetof(NSS_P12_MacData,mac), 38 NSS_P7_DigestInfoTemplate }, 39 { SEC_ASN1_OCTET_STRING, 40 offsetof(NSS_P12_MacData,macSalt) }, 41 /* iterations is unsigned - right? */ 42 { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, 43 offsetof(NSS_P12_MacData,iterations) }, 44 { 0, } 45}; 46 47const SecAsn1Template pointerToMacDataTemplate[] = { 48 { SEC_ASN1_POINTER, 0, NSS_P12_MacDataTemplate } 49}; 50 51/* raw PFX with unprocessed authSafe */ 52const SecAsn1Template NSS_P12_RawPFXTemplate[] = { 53 { SEC_ASN1_SEQUENCE, 54 0, NULL, sizeof(NSS_P12_RawPFX) }, 55 { SEC_ASN1_INTEGER, 56 offsetof(NSS_P12_RawPFX,version) }, 57 { SEC_ASN1_INLINE, 58 offsetof(NSS_P12_RawPFX, authSafe), 59 NSS_P7_RawContentInfoTemplate }, 60 { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL, 61 offsetof(NSS_P12_RawPFX, macData), 62 NSS_P12_MacDataTemplate }, 63 { 0, } 64}; 65 66/* PFX with decoded authSafe */ 67const SecAsn1Template NSS_P12_DecodedPFXTemplate[] = { 68 { SEC_ASN1_SEQUENCE, 69 0, NULL, sizeof(NSS_P12_DecodedPFX) }, 70 { SEC_ASN1_INTEGER, 71 offsetof(NSS_P12_DecodedPFX,version) }, 72 { SEC_ASN1_INLINE, 73 offsetof(NSS_P12_DecodedPFX, authSafe), 74 NSS_P7_DecodedContentInfoTemplate }, 75 { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL, 76 offsetof(NSS_P12_DecodedPFX, macData), 77 NSS_P12_MacDataTemplate }, 78 { 0, } 79}; 80 81/* AuthenticatedSafe */ 82const SecAsn1Template NSS_P12_AuthenticatedSafeTemplate[] = { 83 { SEC_ASN1_SEQUENCE_OF, 84 offsetof(NSS_P12_AuthenticatedSafe, info), 85 NSS_P7_DecodedContentInfoTemplate, 86 sizeof(NSS_P12_AuthenticatedSafe) } 87}; 88 89/* 90 * Individual SafeBag type-specific templates here when we write 'em 91 */ 92const SecAsn1Template NSS_P12_PtrToShroudedKeyBagTemplate[] = { 93 { SEC_ASN1_POINTER, 0, kSecAsn1EncryptedPrivateKeyInfoTemplate } 94}; 95 96/* 97 * CertBag via SEC_ASN1_DYNAMIC 98 */ 99static const SecAsn1Template * NSS_P12_CertBagChooser( 100 void *arg, // --> NSS_P12_CertBag 101 Boolean enc, 102 const char *buf, // on decode, tag byte 103 void *dest) // --> NSS_P12_CertBag.bagValue 104{ 105 NSS_P12_CertBag *bag = (NSS_P12_CertBag *)arg; 106 const SecAsn1Template *templ = NULL; 107 NSS_P12_CertBagType type = CT_Unknown; 108 SecAsn1Oid *oid = &bag->bagType; 109 110 if(nssCompareSecAsn1Items(oid, &CSSMOID_PKCS9_X509Certificate)) { 111 templ = kSecAsn1OctetStringTemplate; 112 type = CT_X509; 113 } 114 else if(nssCompareSecAsn1Items(oid, &CSSMOID_PKCS9_SdsiCertificate)) { 115 templ = kSecAsn1IA5StringTemplate; 116 type = CT_SDSI; 117 } 118 else { 119 /* punt */ 120 templ = kSecAsn1AnyTemplate; 121 } 122 if(!enc) { 123 bag->type = type; 124 } 125 return templ; 126} 127 128static const SecAsn1TemplateChooserPtr NSS_P12_CertBagChooserPtr = 129 NSS_P12_CertBagChooser; 130 131const SecAsn1Template NSS_P12_CertBagTemplate[] = { 132 { SEC_ASN1_SEQUENCE, 133 0, NULL, sizeof(NSS_P12_CertBag) }, 134 { SEC_ASN1_OBJECT_ID, 135 offsetof(NSS_P12_CertBag,bagType) }, 136 /* these come in with a tag of 0xA0, context/constructed, 137 * though I don't know why they are flagged as constructed */ 138 { SEC_ASN1_DYNAMIC | SEC_ASN1_CONTEXT_SPECIFIC | 139 SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | 0, 140 offsetof(NSS_P12_CertBag, certValue), 141 &NSS_P12_CertBagChooserPtr }, 142 { 0, } 143}; 144 145const SecAsn1Template NSS_P12_PtrToCertBagTemplate[] = { 146 { SEC_ASN1_POINTER, 0, NSS_P12_CertBagTemplate } 147}; 148 149/* 150 * CrlBag via SEC_ASN1_DYNAMIC 151 */ 152static const SecAsn1Template * NSS_P12_CrlBagChooser( 153 void *arg, // --> NSS_P12_CrlBag 154 Boolean enc, 155 const char *buf, // on decode, tag byte 156 void *dest) // --> NSS_P12_CertBag.bagValue 157{ 158 NSS_P12_CrlBag *bag = (NSS_P12_CrlBag *)arg; 159 const SecAsn1Template *templ = NULL; 160 NSS_P12_CrlBagType type = CRT_Unknown; 161 SecAsn1Oid *oid = &bag->bagType; 162 163 if(nssCompareSecAsn1Items(oid, &CSSMOID_PKCS9_X509Crl)) { 164 templ = kSecAsn1OctetStringTemplate; 165 type = CRT_X509; 166 } 167 else { 168 /* punt */ 169 templ = kSecAsn1AnyTemplate; 170 } 171 if(!enc) { 172 bag->type = type; 173 } 174 return templ; 175} 176 177static const SecAsn1TemplateChooserPtr NSS_P12_CrlBagChooserPtr = 178 NSS_P12_CrlBagChooser; 179 180const SecAsn1Template NSS_P12_CrlBagTemplate[] = { 181 { SEC_ASN1_SEQUENCE, 182 0, NULL, sizeof(NSS_P12_CrlBag) }, 183 { SEC_ASN1_OBJECT_ID, 184 offsetof(NSS_P12_CrlBag,bagType) }, 185 /* these come in with a tag of 0xA0, context/constructed, 186 * though I don't know why they are flagged as constructed */ 187 { SEC_ASN1_DYNAMIC | SEC_ASN1_CONTEXT_SPECIFIC | 188 SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | 0, 189 offsetof(NSS_P12_CrlBag, crlValue), 190 &NSS_P12_CrlBagChooserPtr }, 191 { 0, } 192}; 193 194const SecAsn1Template NSS_P12_PtrToCrlBagTemplate[] = { 195 { SEC_ASN1_POINTER, 0, NSS_P12_CrlBagTemplate } 196}; 197 198 199/* the stub templates for unimplemented BagTypes */ 200#define NSS_P12_PtrToKeyBagTemplate kSecAsn1PointerToAnyTemplate 201#define NSS_P12_PtrToSecretBagTemplate kSecAsn1PointerToAnyTemplate 202#define NSS_P12_PtrToSafeContentsBagTemplate kSecAsn1PointerToAnyTemplate 203 204 205/* 206 * SafeBag via SEC_ASN1_DYNAMIC 207 */ 208static const SecAsn1Template * NSS_P12_SafeBagChooser( 209 void *arg, // --> NSS_P12_SafeBag 210 Boolean enc, 211 const char *buf, // on decode, tag byte 212 void *dest) // --> NSS_P12_SafeBag.bagValue 213{ 214 NSS_P12_SafeBag *bag = (NSS_P12_SafeBag *)arg; 215 const SecAsn1Template *templ = NULL; 216 NSS_P12_SB_Type type = BT_None; 217 SecAsn1Oid *oid = &bag->bagId; 218 219 if(nssCompareSecAsn1Items(oid, &CSSMOID_PKCS12_keyBag)) { 220 templ = NSS_P12_PtrToKeyBagTemplate; 221 type = BT_KeyBag; 222 } 223 else if(nssCompareSecAsn1Items(oid, &CSSMOID_PKCS12_shroudedKeyBag)) { 224 templ = NSS_P12_PtrToShroudedKeyBagTemplate; 225 type = BT_ShroudedKeyBag; 226 } 227 else if(nssCompareSecAsn1Items(oid, &CSSMOID_PKCS12_certBag)) { 228 templ = NSS_P12_PtrToCertBagTemplate; 229 type = BT_CertBag; 230 } 231 else if(nssCompareSecAsn1Items(oid, &CSSMOID_PKCS12_crlBag)) { 232 templ = NSS_P12_PtrToCrlBagTemplate; 233 type = BT_CrlBag; 234 } 235 else if(nssCompareSecAsn1Items(oid, &CSSMOID_PKCS12_secretBag)) { 236 templ = NSS_P12_PtrToSecretBagTemplate; 237 type = BT_SecretBag; 238 } 239 else if(nssCompareSecAsn1Items(oid, &CSSMOID_PKCS12_safeContentsBag)) { 240 templ = NSS_P12_PtrToSafeContentsBagTemplate; 241 type = BT_SafeContentsBag; 242 } 243 /* add more here when we implement them */ 244 else { 245 templ = kSecAsn1PointerToAnyTemplate; 246 } 247 if(!enc) { 248 bag->type = type; 249 } 250 return templ; 251} 252 253static const SecAsn1TemplateChooserPtr NSS_P12_SafeBagChooserPtr = 254 NSS_P12_SafeBagChooser; 255 256const SecAsn1Template NSS_P12_SafeBagTemplate[] = { 257 { SEC_ASN1_SEQUENCE, 258 0, NULL, sizeof(NSS_P12_SafeBag) }, 259 { SEC_ASN1_OBJECT_ID, 260 offsetof(NSS_P12_SafeBag,bagId) }, 261 { SEC_ASN1_DYNAMIC | SEC_ASN1_CONSTRUCTED | 262 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 0, 263 offsetof(NSS_P12_SafeBag,bagValue), 264 &NSS_P12_SafeBagChooserPtr }, 265 { SEC_ASN1_OPTIONAL | SEC_ASN1_SET_OF, 266 offsetof(NSS_P12_SafeBag,bagAttrs), 267 kSecAsn1AttributeTemplate }, 268 { 0 } 269}; 270 271const SecAsn1Template NSS_P12_SafeContentsTemplate[] = { 272 { SEC_ASN1_SEQUENCE_OF, 273 offsetof(NSS_P12_SafeContents, bags), 274 NSS_P12_SafeBagTemplate, 275 sizeof(NSS_P12_SafeContents) } 276}; 277 278const SecAsn1Template NSS_P12_PBE_ParamsTemplate[] = { 279 { SEC_ASN1_SEQUENCE, 280 0, NULL, sizeof(NSS_P12_PBE_Params) }, 281 { SEC_ASN1_OCTET_STRING, 282 offsetof(NSS_P12_PBE_Params,salt) }, 283 /* iterations is unsigned - right? */ 284 { SEC_ASN1_INTEGER, 285 offsetof(NSS_P12_PBE_Params,iterations) }, 286 { 0 } 287}; 288 289 290