]> git.saurik.com Git - apple/security.git/blob - SecureTransport/sslBER.cpp
Security-30.1.tar.gz
[apple/security.git] / SecureTransport / sslBER.cpp
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 File: sslBER.cpp
21
22 Contains: BER routines
23
24 Written by: Doug Mitchell
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29
30 #include "ssl.h"
31 #include "sslalloc.h"
32 #include "sslDebug.h"
33 #include "sslBER.h"
34
35 #include <Security/asn-incl.h>
36 #include <Security/sm_vdatypes.h>
37 #include <Security/asn-type.h>
38 #include <Security/pkcs1oids.h> /* for RSAPublicKey */
39 #include <Security/cdsaUtils.h>
40 #include <string.h>
41 #include <Security/cssmdata.h>
42
43 /* convert between SSLBuffer and snacc-style BigIntegerStr */
44
45 static void snaccIntToData(
46 const BigIntegerStr &snaccInt,
47 SSLBuffer *outData) // already mallocd
48 {
49 const char *scp = snaccInt;
50 uint8 *cp = (uint8 *)scp;
51 uint32 len = snaccInt.Len();
52
53 if (*cp == 0x00) {
54 /* skip over this place-holding m.s. byte */
55 cp++;
56 len--;
57 }
58
59 memmove(outData->data, cp, len);
60 outData->length = len;
61 }
62
63 static void dataToSnaccInt(
64 const SSLBuffer *inData,
65 BigIntegerStr &snaccInt)
66 {
67 uint8 *cp;
68 int msbIsSet = 0;
69
70 if (inData->data[0] & 0x80) {
71 /* m.s. bit of BER data must be zero! */
72 cp = (uint8 *)malloc(inData->length + 1);
73 *cp = 0;
74 memmove(cp+1, inData->data, inData->length);
75 msbIsSet = 1;
76 }
77 else {
78 cp = inData->data;
79 }
80 snaccInt.Set(reinterpret_cast<const char *>(cp),
81 inData->length + msbIsSet);
82 if(msbIsSet) {
83 free(cp);
84 }
85 }
86
87 /*
88 * Given a PKCS-1 encoded RSA public key, extract the
89 * modulus and public exponent.
90 *
91 * RSAPublicKey ::= SEQUENCE {
92 * modulus INTEGER, -- n
93 * publicExponent INTEGER -- e }
94 */
95
96 SSLErr sslDecodeRsaBlob(
97 const SSLBuffer *blob, /* PKCS-1 encoded */
98 SSLBuffer *modulus, /* data mallocd and RETURNED */
99 SSLBuffer *exponent) /* data mallocd and RETURNED */
100 {
101 SSLErr srtn;
102
103 CASSERT(blob != NULL);
104 CASSERT(modulus != NULL);
105 CASSERT(exponent != NULL);
106
107 /* DER-decode the blob */
108 RSAPublicKey snaccPubKey;
109 CssmData cssmBlob(blob->data, blob->length);
110 try {
111 SC_decodeAsnObj(cssmBlob, snaccPubKey);
112 }
113 catch(...) {
114 return SSLBadCert;
115 }
116
117 /* malloc & convert components */
118 srtn = SSLAllocBuffer(modulus, snaccPubKey.modulus.Len(), NULL);
119 if(srtn) {
120 return srtn;
121 }
122 snaccIntToData(snaccPubKey.modulus, modulus);
123 srtn = SSLAllocBuffer(exponent, snaccPubKey.publicExponent.Len(),
124 NULL);
125 if(srtn) {
126 return srtn;
127 }
128 snaccIntToData(snaccPubKey.publicExponent, exponent);
129 return SSLNoErr;
130 }
131
132 /*
133 * Given a raw modulus and exponent, cook up a
134 * BER-encoded RSA public key blob.
135 */
136 SSLErr sslEncodeRsaBlob(
137 const SSLBuffer *modulus,
138 const SSLBuffer *exponent,
139 SSLBuffer *blob) /* data mallocd and RETURNED */
140 {
141 CASSERT((modulus != NULL) && (exponent != NULL));
142 blob->data = NULL;
143 blob->length = 0;
144
145 /* Cook up a snacc-style RSAPublic key */
146 RSAPublicKey snaccPubKey;
147 dataToSnaccInt(modulus, snaccPubKey.modulus);
148 dataToSnaccInt(exponent, snaccPubKey.publicExponent);
149
150 /* estimate max size, BER-encode */
151 size_t maxSize = 2 * (modulus->length + exponent->length);
152 CssmAllocator &alloc = CssmAllocator::standard();
153 CssmAutoData cblob(alloc);
154 try {
155 SC_encodeAsnObj(snaccPubKey, cblob, maxSize);
156 }
157 catch(...) {
158 /* right...? */
159 return SSLMemoryErr;
160 }
161
162 /* copy to caller's SSLBuffer */
163 SSLErr srtn = SSLAllocBuffer(blob, cblob.length(), NULL);
164 if(srtn) {
165 return srtn;
166 }
167 memmove(blob->data, cblob.data(), cblob.length());
168 return SSLNoErr;
169 }
170