2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 * CertBuilder.cpp - sublasses of various snacc-generated cert-related
23 * Created 9/1/2000 by Doug Mitchell.
24 * Copyright (c) 2000 by Apple Computer.
27 #include "CertBuilder.h"
28 #include <Security/cssmerr.h>
29 #include <Security/utilities.h>
30 #include "cldebugging.h"
32 #define BUF_ENC_EXTRA 64
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.
42 * Typically the object manipulated here is inserted into a
43 * CertificateToSign object, as issuer or subject.
45 void NameBuilder::addATDV(
46 const AsnOid
&type
, // id_at_commonName, etc. from sm_x501if
47 const char *value
, // the bytes
49 DirectoryString::ChoiceIdEnum stringType
,
50 // printableStringCid, etc.
52 bool primaryDistinguished
)
54 /* cook up the RDN sequence first time thru */
55 if(rDNSequence
== NULL
) {
56 rDNSequence
= new RDNSequence
;
57 choiceId
= rDNSequenceCid
; // no others available
60 /* one RelativeDistinguishedName and one ATDV */
61 RelativeDistinguishedName
*rdn
= rDNSequence
->Append();
62 AttributeTypeAndDistinguishedValue
*atdv
= rdn
->Append();
66 * FIXME - AttributeTypeAndDistinguishedValueSetOf??? What's that?
69 if(!primaryDistinguished
) {
70 /* default is true, only encode if not default */
71 atdv
->primaryDistinguished
= new AsnBool(primaryDistinguished
);
74 /* DirectoryString from sm_x520sa */
75 DirectoryString dirStr
;
76 dirStr
.choiceId
= stringType
;
78 case DirectoryString::teletexStringCid
:
79 dirStr
.teletexString
= new TeletexString(value
, valueLen
);
81 case DirectoryString::printableStringCid
:
82 dirStr
.printableString
= new PrintableString(value
, valueLen
);
84 case DirectoryString::universalStringCid
:
85 dirStr
.universalString
= new UniversalString(value
, valueLen
);
87 case DirectoryString::bmpStringCid
:
88 dirStr
.bmpString
= new BMPString(value
, valueLen
);
90 case DirectoryString::utf8StringCid
:
91 dirStr
.utf8String
= new UTF8String(value
, valueLen
);
96 * As far as I can tell, atdv->value.value is a CSM_Buffer containing
97 * the encoded dirStr. First malloc a dest buffer...
99 size_t bufLen
= valueLen
+ BUF_ENC_EXTRA
;
100 char *buf
= (char *)calloc(1, bufLen
);
102 CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR
);
105 /* encode dirStr --> abuf */
107 abuf
.Init(buf
, bufLen
);
108 abuf
.ResetInWriteRvsMode();
111 dirStr
.BEncPdu(abuf
, bytesEnc
);
112 if(bytesEnc
> bufLen
)
114 bytesEnc
= dirStr
.BEnc(abuf
);
115 if(abuf
.WriteError() || (bytesEnc
> bufLen
))
116 #endif /* SNACC_ENABLE_PDU */
119 printf("Whoops! Buffer overflow\n");
124 /* install the result into CSM_Buffer, which mallocs & copies */
125 atdv
->value
.value
= new CSM_Buffer(abuf
.DataPtr(), abuf
.DataLen());
129 void NameBuilder::addX509Name (
130 const CSSM_X509_NAME
*x509Name
)
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
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
);
146 CSSM_X509_TYPE_VALUE_PAIR_PTR atv
= rdn
->AttributeTypeAndValue
;
148 oid
.Set(reinterpret_cast<char *>(atv
->type
.Data
), atv
->type
.Length
);
150 DirectoryString::ChoiceIdEnum stringType
;
151 switch(atv
->valueType
) {
152 case BER_TAG_T61_STRING
:
153 stringType
= DirectoryString::teletexStringCid
;
155 case BER_TAG_PRINTABLE_STRING
:
156 stringType
= DirectoryString::printableStringCid
;
158 case BER_TAG_PKIX_UNIVERSAL_STRING
:
159 stringType
= DirectoryString::universalStringCid
;
161 case BER_TAG_PKIX_BMP_STRING
:
162 stringType
= DirectoryString::bmpStringCid
;
164 case BER_TAG_PKIX_UTF8_STRING
:
165 stringType
= DirectoryString::utf8StringCid
;
168 errorLog1("setField_RDN: illegal tag(%d)\n", atv
->valueType
);
169 CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER
);
172 reinterpret_cast<char *>(atv
->value
.Data
),
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).
184 OidBuilder::OidBuilder(const CSSM_OID
&coid
)
186 oid
= Asn1Alloc (coid
.Length
);
187 memcpy(oid
, coid
.Data
, coid
.Length
);
188 octetLen
= coid
.Length
;