]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 A |
1 | /* |
2 | * Copyright (c) 2003-2004 Apple Computer, 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 | /* | |
25 | * pkcs12BagAttrs.cpp : internal representation of P12 SafeBag | |
26 | * attribute, OTHER THAN friendlyName and localKeyId. | |
27 | * This corresponds to a SecPkcs12AttrsRef at the | |
28 | * public API layer. | |
29 | */ | |
30 | ||
31 | #include "pkcs12BagAttrs.h" | |
32 | #include "pkcs12Utils.h" | |
33 | #include <security_asn1/nssUtils.h> | |
34 | #include <assert.h> | |
35 | #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h> | |
36 | ||
37 | /* | |
38 | * Copying constructor used by P12SafeBag during encoding | |
39 | */ | |
40 | P12BagAttrs::P12BagAttrs( | |
41 | const P12BagAttrs *otherAttrs, | |
42 | SecNssCoder &coder) | |
43 | : mAttrs(NULL), mCoder(coder) | |
44 | { | |
45 | if(otherAttrs == NULL) { | |
46 | /* empty copy, done */ | |
47 | return; | |
48 | } | |
49 | unsigned num = otherAttrs->numAttrs(); | |
50 | reallocAttrs(num); | |
51 | for(unsigned dex=0; dex<num; dex++) { | |
52 | copyAttr(*otherAttrs->mAttrs[dex], *mAttrs[dex]); | |
53 | } | |
54 | } | |
55 | ||
56 | unsigned P12BagAttrs::numAttrs() const | |
57 | { | |
58 | return nssArraySize((const void **)mAttrs); | |
59 | } | |
60 | ||
61 | NSS_Attribute *P12BagAttrs::getAttr( | |
62 | unsigned attrNum) | |
63 | { | |
64 | assert(attrNum < numAttrs()); | |
65 | return mAttrs[attrNum]; | |
66 | } | |
67 | ||
68 | ||
69 | /* | |
70 | * Add an attr during decode. | |
71 | */ | |
72 | void P12BagAttrs::addAttr( | |
73 | const NSS_Attribute &attr) | |
74 | { | |
75 | NSS_Attribute *newAttr = reallocAttrs(numAttrs() + 1); | |
76 | copyAttr(attr, *newAttr); | |
77 | } | |
78 | ||
79 | /* | |
80 | * Add an attr during encode. | |
81 | */ | |
82 | void P12BagAttrs::addAttr( | |
83 | const CFDataRef attrOid, | |
84 | const CFArrayRef attrValues) | |
85 | { | |
86 | NSS_Attribute *newAttr = reallocAttrs(numAttrs() + 1); | |
87 | p12CfDataToCssm(attrOid, newAttr->attrType, mCoder); | |
88 | unsigned numVals = CFArrayGetCount(attrValues); | |
89 | newAttr->attrValue = (CSSM_DATA **)p12NssNullArray(numVals, mCoder); | |
90 | for(unsigned dex=0; dex<numVals; dex++) { | |
91 | CSSM_DATA *dstVal = (CSSM_DATA *)mCoder.malloc(sizeof(CSSM_DATA)); | |
92 | newAttr->attrValue[dex] = dstVal; | |
93 | CFDataRef srcVal = (CFDataRef)CFArrayGetValueAtIndex(attrValues, dex); | |
94 | assert(CFGetTypeID(srcVal) == CFDataGetTypeID()); | |
95 | p12CfDataToCssm(srcVal, *dstVal, mCoder); | |
96 | } | |
97 | } | |
98 | ||
99 | /* | |
100 | * getter, public API version | |
101 | */ | |
102 | void P12BagAttrs::getAttr( | |
103 | unsigned attrNum, | |
104 | CFDataRef *attrOid, // RETURNED | |
105 | CFArrayRef *attrValues) // RETURNED | |
106 | { | |
107 | if(attrNum >= numAttrs()) { | |
108 | MacOSError::throwMe(paramErr); | |
109 | } | |
110 | NSS_Attribute *attr = mAttrs[attrNum]; | |
111 | *attrOid = p12CssmDataToCf(attr->attrType); | |
112 | unsigned numVals = nssArraySize((const void **)attr->attrValue); | |
113 | if(numVals == 0) { | |
114 | /* maybe should return empty array...? */ | |
115 | *attrValues = NULL; | |
116 | return; | |
117 | } | |
118 | CFMutableArrayRef vals = CFArrayCreateMutable(NULL, numVals, NULL); | |
119 | for(unsigned dex=0; dex<numVals; dex++) { | |
120 | CFDataRef val = p12CssmDataToCf(*attr->attrValue[dex]); | |
121 | CFArrayAppendValue(vals, val); | |
122 | } | |
123 | *attrValues = vals; | |
124 | } | |
125 | ||
126 | #pragma mark --- private methods --- | |
127 | ||
128 | /* | |
129 | * Alloc/realloc attr array. | |
130 | * Returns ptr to new empty NSS_Attribute for insertion. | |
131 | */ | |
132 | NSS_Attribute *P12BagAttrs::reallocAttrs( | |
133 | size_t numNewAttrs) | |
134 | { | |
135 | unsigned curSize = numAttrs(); | |
136 | assert(numNewAttrs > curSize); | |
137 | NSS_Attribute **newAttrs = | |
138 | (NSS_Attribute **)p12NssNullArray(numNewAttrs, mCoder); | |
139 | for(unsigned dex=0; dex<curSize; dex++) { | |
140 | newAttrs[dex] = mAttrs[dex]; | |
141 | } | |
142 | mAttrs = newAttrs; | |
143 | ||
144 | /* allocate new NSS_Attributes */ | |
145 | for(unsigned dex=curSize; dex<numNewAttrs; dex++) { | |
146 | mAttrs[dex] = mCoder.mallocn<NSS_Attribute>(); | |
147 | memset(mAttrs[dex], 0, sizeof(NSS_Attribute)); | |
148 | } | |
149 | return mAttrs[curSize]; | |
150 | } | |
151 | ||
152 | void P12BagAttrs::copyAttr( | |
153 | const NSS_Attribute &src, | |
154 | NSS_Attribute &dst) | |
155 | { | |
156 | mCoder.allocCopyItem(src.attrType, dst.attrType); | |
157 | unsigned numVals = nssArraySize((const void **)src.attrValue); | |
158 | dst.attrValue = (CSSM_DATA **)p12NssNullArray(numVals, mCoder); | |
159 | for(unsigned dex=0; dex<numVals; dex++) { | |
160 | CSSM_DATA *dstVal = mCoder.mallocn<CSSM_DATA>(); | |
161 | memset(dstVal, 0, sizeof(CSSM_DATA)); | |
162 | dst.attrValue[dex] = dstVal; | |
163 | mCoder.allocCopyItem(*src.attrValue[dex], *dstVal); | |
164 | } | |
165 | } |