]> git.saurik.com Git - apple/security.git/blob - SecureTransport/sslBER.cpp
Security-163.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 "sslMemory.h"
32 #include "sslDebug.h"
33 #include "sslBER.h"
34 #include "appleCdsa.h"
35
36 #include <string.h>
37 #include <Security/cssmdata.h>
38 #include <SecurityNssAsn1/SecNssCoder.h>
39 #include <SecurityNssAsn1/keyTemplates.h>
40
41 /*
42 * Given a PKCS-1 encoded RSA public key, extract the
43 * modulus and public exponent.
44 *
45 * RSAPublicKey ::= SEQUENCE {
46 * modulus INTEGER, -- n
47 * publicExponent INTEGER -- e }
48 */
49
50 OSStatus sslDecodeRsaBlob(
51 const SSLBuffer *blob, /* PKCS-1 encoded */
52 SSLBuffer *modulus, /* data mallocd and RETURNED */
53 SSLBuffer *exponent) /* data mallocd and RETURNED */
54 {
55 OSStatus srtn;
56
57 assert(blob != NULL);
58 assert(modulus != NULL);
59 assert(exponent != NULL);
60
61 /* DER-decode the blob */
62 NSS_RSAPublicKeyPKCS1 nssPubKey;
63 SecNssCoder coder;
64
65 memset(&nssPubKey, 0, sizeof(nssPubKey));
66 PRErrorCode perr = coder.decode(blob->data, blob->length,
67 NSS_RSAPublicKeyPKCS1Template, &nssPubKey);
68 if(perr) {
69 return errSSLBadCert;
70 }
71
72 /* malloc & copy components */
73 srtn = SSLCopyBufferFromData(nssPubKey.modulus.Data,
74 nssPubKey.modulus.Length, *modulus);
75 if(srtn) {
76 return srtn;
77 }
78 return SSLCopyBufferFromData(nssPubKey.publicExponent.Data,
79 nssPubKey.publicExponent.Length, *exponent);
80 }
81
82 /*
83 * Given a raw modulus and exponent, cook up a
84 * BER-encoded RSA public key blob.
85 */
86 OSStatus sslEncodeRsaBlob(
87 const SSLBuffer *modulus,
88 const SSLBuffer *exponent,
89 SSLBuffer *blob) /* data mallocd and RETURNED */
90 {
91 assert((modulus != NULL) && (exponent != NULL));
92 blob->data = NULL;
93 blob->length = 0;
94
95 /* convert to NSS_RSAPublicKeyPKCS1 */
96 NSS_RSAPublicKeyPKCS1 nssPubKey;
97 SSLBUF_TO_CSSM(modulus, &nssPubKey.modulus);
98 SSLBUF_TO_CSSM(exponent, &nssPubKey.publicExponent);
99
100 /* DER encode */
101 SecNssCoder coder;
102 CSSM_DATA encBlob;
103 PRErrorCode perr;
104 perr = coder.encodeItem(&nssPubKey, NSS_RSAPublicKeyPKCS1Template, encBlob);
105 if(perr) {
106 return memFullErr;
107
108 }
109 /* copy out to caller */
110 return SSLCopyBufferFromData(encBlob.Data, encBlob.Length, *blob);
111 }
112
113 /*
114 * Given a DER encoded DHParameterBlock, extract the prime and generator.
115 * modulus and public exponent.
116 * This will work with either PKCS-1 encoded DHParameterBlock or
117 * openssl-style DHParameter.
118 */
119 OSStatus sslDecodeDhParams(
120 const SSLBuffer *blob, /* PKCS-1 encoded */
121 SSLBuffer *prime, /* data mallocd and RETURNED */
122 SSLBuffer *generator) /* data mallocd and RETURNED */
123 {
124 assert(blob != NULL);
125 assert(prime != NULL);
126 assert(generator != NULL);
127
128 PRErrorCode perr;
129 NSS_DHParameterBlock paramBlock;
130 SecNssCoder coder;
131 CSSM_DATA cblob;
132
133 memset(&paramBlock, 0, sizeof(paramBlock));
134 SSLBUF_TO_CSSM(blob, &cblob);
135
136 /*
137 * Since the common case here is to decode a parameter block coming
138 * over the wire, which is in openssl format, let's try that format first.
139 */
140 perr = coder.decodeItem(cblob, NSS_DHParameterTemplate,
141 &paramBlock.params);
142 if(perr) {
143 /*
144 * OK, that failed when trying as a CDSA_formatted parameter
145 * block DHParameterBlock). Openssl uses a subset of that,
146 * a DHParameter. Try that instead.
147 */
148 memset(&paramBlock, 0, sizeof(paramBlock));
149 perr = coder.decodeItem(cblob, NSS_DHParameterBlockTemplate,
150 &paramBlock);
151 if(perr) {
152 /* Ah well, we tried. */
153 sslErrorLog("sslDecodeDhParams: both CDSA and openssl format"
154 "failed\n");
155 return errSSLCrypto;
156 }
157 }
158
159 /* copy out components */
160 NSS_DHParameter &param = paramBlock.params;
161 OSStatus ortn = SSLCopyBufferFromData(param.prime.Data,
162 param.prime.Length, *prime);
163 if(ortn) {
164 return ortn;
165 }
166 return SSLCopyBufferFromData(param.base.Data,
167 param.base.Length, *generator);
168 }
169
170 /*
171 * Given a prime and generator, cook up a BER-encoded DHParameter blob.
172 */
173 OSStatus sslEncodeDhParams(
174 const SSLBuffer *prime,
175 const SSLBuffer *generator,
176 SSLBuffer *blob) /* data mallocd and RETURNED */
177 {
178 assert((prime != NULL) && (generator != NULL));
179 blob->data = NULL;
180 blob->length = 0;
181
182 /* convert to NSS_DHParameter */
183 NSS_DHParameter dhParams;
184 SSLBUF_TO_CSSM(prime, &dhParams.prime);
185 SSLBUF_TO_CSSM(generator, &dhParams.base);
186 dhParams.privateValueLength.Data = NULL;
187 dhParams.privateValueLength.Length = 0;
188
189 /* DER encode */
190 SecNssCoder coder;
191 CSSM_DATA encBlob;
192 PRErrorCode perr;
193 perr = coder.encodeItem(&dhParams, NSS_DHParameterTemplate, encBlob);
194 if(perr) {
195 return memFullErr;
196
197 }
198 /* copy out to caller */
199 return SSLCopyBufferFromData(encBlob.Data, encBlob.Length, *blob);
200 }
201