]> git.saurik.com Git - apple/security.git/blame - AppleX509CL/CertBuilder.cpp
Security-54.1.3.tar.gz
[apple/security.git] / AppleX509CL / CertBuilder.cpp
CommitLineData
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 */
45void 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
129void 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 */
184OidBuilder::OidBuilder(const CSSM_OID &coid)
185{
186 oid = Asn1Alloc (coid.Length);
187 memcpy(oid, coid.Data, coid.Length);
188 octetLen = coid.Length;
189}
190