]>
Commit | Line | Data |
---|---|---|
bac41a7b A |
1 | /* |
2 | * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. | |
3 | * | |
4 | * The contents of this file constitute Original Code as defined in and are | |
5 | * subject to the Apple Public Source License Version 1.2 (the 'License'). | |
6 | * You may not use this file except in compliance with the License. Please obtain | |
7 | * a copy of the License at http://www.apple.com/publicsource and read it before | |
8 | * using this file. | |
9 | * | |
10 | * This Original Code and all software distributed under the License are | |
11 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS | |
12 | * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT | |
13 | * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |
14 | * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the | |
15 | * specific language governing rights and limitations under the License. | |
16 | */ | |
17 | ||
18 | ||
19 | /* | |
20 | * CertBuilder.cpp - sublasses of various snacc-generated cert-related | |
21 | * classes. | |
22 | * | |
23 | * Created 9/1/2000 by Doug Mitchell. | |
24 | * Copyright (c) 2000 by Apple Computer. | |
25 | */ | |
26 | ||
27 | #include "CertBuilder.h" | |
28 | #include <Security/cssmerr.h> | |
29 | #include <Security/utilities.h> | |
29654253 | 30 | #include "cldebugging.h" |
bac41a7b A |
31 | |
32 | #define BUF_ENC_EXTRA 64 | |
33 | ||
34 | /* | |
35 | * Name is a complex structure which boils down to an arbitrarily | |
36 | * large array of (usually) printable names. We facilitate the | |
37 | * construction of the array, one AttributeTypeAndDistinguishedValue | |
38 | * per RelativeDistinguishedName. This is the format commonly used | |
39 | * in the real world, though it's legal to have multiple ATDVs | |
40 | * per RDN - we just don't do it here. | |
41 | * | |
42 | * Typically the object manipulated here is inserted into a | |
43 | * CertificateToSign object, as issuer or subject. | |
44 | */ | |
45 | void NameBuilder::addATDV( | |
46 | const AsnOid &type, // id_at_commonName, etc. from sm_x501if | |
47 | const char *value, // the bytes | |
48 | size_t valueLen, | |
49 | DirectoryString::ChoiceIdEnum stringType, | |
50 | // printableStringCid, etc. | |
51 | // from sm_x520sa | |
52 | bool primaryDistinguished) | |
53 | { | |
54 | /* cook up the RDN sequence first time thru */ | |
55 | if(rDNSequence == NULL) { | |
56 | rDNSequence = new RDNSequence; | |
57 | choiceId = rDNSequenceCid; // no others available | |
58 | } | |
59 | ||
60 | /* one RelativeDistinguishedName and one ATDV */ | |
61 | RelativeDistinguishedName *rdn = rDNSequence->Append(); | |
62 | AttributeTypeAndDistinguishedValue *atdv = rdn->Append(); | |
63 | ||
64 | /* | |
65 | * fill in the ATDV | |
66 | * FIXME - AttributeTypeAndDistinguishedValueSetOf??? What's that? | |
67 | */ | |
68 | atdv->type = type; | |
69 | if(!primaryDistinguished) { | |
70 | /* default is true, only encode if not default */ | |
71 | atdv->primaryDistinguished = new AsnBool(primaryDistinguished); | |
72 | } | |
73 | ||
74 | /* DirectoryString from sm_x520sa */ | |
75 | DirectoryString dirStr; | |
76 | dirStr.choiceId = stringType; | |
77 | switch(stringType) { | |
78 | case DirectoryString::teletexStringCid: | |
79 | dirStr.teletexString = new TeletexString(value, valueLen); | |
80 | break; | |
81 | case DirectoryString::printableStringCid: | |
82 | dirStr.printableString = new PrintableString(value, valueLen); | |
83 | break; | |
84 | case DirectoryString::universalStringCid: | |
85 | dirStr.universalString = new UniversalString(value, valueLen); | |
86 | break; | |
87 | case DirectoryString::bmpStringCid: | |
88 | dirStr.bmpString = new BMPString(value, valueLen); | |
89 | break; | |
90 | case DirectoryString::utf8StringCid: | |
91 | dirStr.utf8String = new UTF8String(value, valueLen); | |
92 | break; | |
93 | } | |
94 | ||
95 | /* | |
96 | * As far as I can tell, atdv->value.value is a CSM_Buffer containing | |
97 | * the encoded dirStr. First malloc a dest buffer... | |
98 | */ | |
99 | size_t bufLen = valueLen + BUF_ENC_EXTRA; | |
100 | char *buf = (char *)calloc(1, bufLen); | |
101 | if(buf == NULL) { | |
102 | CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR); | |
103 | } | |
104 | ||
105 | /* encode dirStr --> abuf */ | |
106 | AsnBuf abuf; | |
107 | abuf.Init(buf, bufLen); | |
108 | abuf.ResetInWriteRvsMode(); | |
109 | AsnLen bytesEnc; | |
29654253 | 110 | #if SNACC_ENABLE_PDU |
bac41a7b | 111 | dirStr.BEncPdu(abuf, bytesEnc); |
29654253 A |
112 | if(bytesEnc > bufLen) |
113 | #else | |
114 | bytesEnc = dirStr.BEnc(abuf); | |
115 | if(abuf.WriteError() || (bytesEnc > bufLen)) | |
116 | #endif /* SNACC_ENABLE_PDU */ | |
117 | { | |
bac41a7b A |
118 | #ifndef NDEBUG |
119 | printf("Whoops! Buffer overflow\n"); | |
120 | #endif | |
121 | /* throw */ | |
122 | } | |
123 | ||
124 | /* install the result into CSM_Buffer, which mallocs & copies */ | |
125 | atdv->value.value = new CSM_Buffer(abuf.DataPtr(), abuf.DataLen()); | |
126 | free(buf); | |
127 | } | |
128 | ||
29654253 A |
129 | void NameBuilder::addX509Name ( |
130 | const CSSM_X509_NAME *x509Name) | |
131 | { | |
132 | /* | |
133 | * The main job here is extracting attr/value pairs in CSSM format | |
134 | * from x509Name, and converting them into arguments for addATDV. | |
135 | * Note that we're taking the default for primaryDistinguished, | |
136 | * because the CDSA CSSM_X509_TYPE_VALUE_PAIR struct doesn't allow for | |
137 | * it. | |
138 | */ | |
139 | for(unsigned rdnDex=0; rdnDex<x509Name->numberOfRDNs; rdnDex++) { | |
140 | CSSM_X509_RDN_PTR rdn = &x509Name->RelativeDistinguishedName[rdnDex]; | |
141 | if(rdn->numberOfPairs != 1) { | |
142 | errorLog0("setField_RDN: only one a/v pair per RDN supported\n"); | |
143 | CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER); | |
144 | } | |
145 | ||
146 | CSSM_X509_TYPE_VALUE_PAIR_PTR atv = rdn->AttributeTypeAndValue; | |
147 | AsnOid oid; | |
148 | oid.Set(reinterpret_cast<char *>(atv->type.Data), atv->type.Length); | |
149 | ||
150 | DirectoryString::ChoiceIdEnum stringType; | |
151 | switch(atv->valueType) { | |
152 | case BER_TAG_T61_STRING: | |
153 | stringType = DirectoryString::teletexStringCid; | |
154 | break; | |
155 | case BER_TAG_PRINTABLE_STRING: | |
156 | stringType = DirectoryString::printableStringCid; | |
157 | break; | |
158 | case BER_TAG_PKIX_UNIVERSAL_STRING: | |
159 | stringType = DirectoryString::universalStringCid; | |
160 | break; | |
161 | case BER_TAG_PKIX_BMP_STRING: | |
162 | stringType = DirectoryString::bmpStringCid; | |
163 | break; | |
164 | case BER_TAG_PKIX_UTF8_STRING: | |
165 | stringType = DirectoryString::utf8StringCid; | |
166 | break; | |
167 | default: | |
168 | errorLog1("setField_RDN: illegal tag(%d)\n", atv->valueType); | |
169 | CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER); | |
170 | } | |
171 | addATDV(oid, | |
172 | reinterpret_cast<char *>(atv->value.Data), | |
173 | atv->value.Length, | |
174 | stringType); | |
175 | } | |
176 | } | |
177 | ||
178 | ||
bac41a7b A |
179 | /* |
180 | * Custom AsnOid, used for converting CssmOid to AsnOid. The Snacc class | |
181 | * declaration doesn't provide a means to construct from, or set by, | |
182 | * pre-encoded OID bytes (which are available in a CssmOid). | |
183 | */ | |
184 | OidBuilder::OidBuilder(const CSSM_OID &coid) | |
185 | { | |
186 | oid = Asn1Alloc (coid.Length); | |
187 | memcpy(oid, coid.Data, coid.Length); | |
188 | octetLen = coid.Length; | |
189 | } | |
190 |