]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_apple_csp/open_ssl/opensslUtils/opensslUtils.cpp
Security-57740.51.3.tar.gz
[apple/security.git] / OSX / libsecurity_apple_csp / open_ssl / opensslUtils / opensslUtils.cpp
1 /*
2 * Copyright (c) 2000-2001,2011,2014 Apple 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 * opensslUtils.h - Support for ssleay-derived crypto modules
21 */
22
23 #include <openssl/rand.h>
24 #include <openssl/crypto_legacy.h>
25 #include <openssl/opensslerr.h>
26 #include <openssl/sha.h>
27 #include <openssl/rsa_legacy.h>
28 #include <openssl/dsa_legacy.h>
29 #include <openssl/dh_legacy.h>
30 #include <openssl/opensslerr.h>
31 #include <security_utilities/debugging.h>
32 #include <Security/cssmerr.h>
33 #include "opensslUtils.h"
34 #include <YarrowConnection.h>
35 #include <AppleCSPUtils.h>
36 #include <security_utilities/logging.h>
37
38 #define sslUtilsDebug(args...) secinfo("sslUtils", ## args)
39
40 openSslException::openSslException(
41 int irtn,
42 const char *op)
43 : mIrtn(irtn)
44 {
45 if(op) {
46 char buf[300];
47 ERR_error_string(irtn, buf);
48 sslUtilsDebug("%s: %s\n", op, buf);
49 }
50 }
51
52 /* these are replacements for the ones in ssleay */
53 #define DUMP_RAND_BYTES 0
54
55 static int randDex = 1;
56
57 int RAND_bytes(unsigned char *buf,int num)
58 {
59 try {
60 cspGetRandomBytes(buf, (unsigned)num);
61 }
62 catch(...) {
63 /* that can only mean Yarrow failure, which we really need to
64 * cut some slack for */
65 Security::Syslog::error("Apple CSP: yarrow failure");
66 for(int i=0; i<num; i++) {
67 buf[i] = (i*3) + randDex++;
68 }
69 }
70 return 1;
71 }
72
73 int RAND_pseudo_bytes(unsigned char *buf,int num)
74 {
75 return RAND_bytes(buf, num);
76 }
77
78 void RAND_add(const void *buf,int num,double entropy)
79 {
80 try {
81 cspAddEntropy(buf, (unsigned)num);
82 }
83 catch(...) {
84 }
85 }
86
87 /* replacement for mem_dbg.c */
88 int CRYPTO_mem_ctrl(int mode)
89 {
90 return 0;
91 }
92
93 /* Clear openssl error stack. */
94 void clearOpensslErrors()
95 {
96 while(ERR_get_error())
97 ;
98 }
99
100 /*
101 * Log error info. Returns the error code we pop off the error queue.
102 */
103 unsigned long logSslErrInfo(const char *op)
104 {
105 unsigned long e = ERR_get_error();
106
107 /* flush out subsequent errors; we only want the first one */
108 clearOpensslErrors();
109
110 char outbuf[1024];
111 ERR_error_string(e, outbuf);
112 if(op) {
113 Security::Syslog::error("Apple CSP %s: %s", op, outbuf);
114 }
115 else {
116 Security::Syslog::error("Apple CSP %s", outbuf);
117 }
118 return e;
119 }
120
121 /*
122 * Replacement for same function in openssl's sha.c, which we don't link against.
123 * The only place this is used is in DSA_generate_parameters().
124 */
125 unsigned char *SHA1(const unsigned char *d, unsigned long n,unsigned char *md)
126 {
127 if(md == NULL) {
128 sslUtilsDebug("SHA1 with NULL md");
129 CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
130 }
131 cspGenSha1Hash(d, n, md);
132 return md;
133 }
134
135 void throwRsaDsa(
136 const char *op)
137 {
138 unsigned long e = logSslErrInfo(op);
139 CSSM_RETURN cerr = CSSM_OK;
140
141 /* try to parse into something meaningful */
142 int reason = ERR_GET_REASON(e);
143 int lib = ERR_GET_LIB(e);
144
145 /* first try the global ones */
146 switch(reason) {
147 case ERR_R_MALLOC_FAILURE:
148 cerr = CSSMERR_CSP_MEMORY_ERROR; break;
149 case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED:
150 /* internal */ break;
151 case ERR_R_PASSED_NULL_PARAMETER:
152 cerr = CSSMERR_CSP_INVALID_POINTER; break;
153 case ERR_R_NESTED_ASN1_ERROR:
154 case ERR_R_BAD_ASN1_OBJECT_HEADER:
155 case ERR_R_BAD_GET_ASN1_OBJECT_CALL:
156 case ERR_R_EXPECTING_AN_ASN1_SEQUENCE:
157 case ERR_R_ASN1_LENGTH_MISMATCH:
158 case ERR_R_MISSING_ASN1_EOS:
159 /* ASN - shouldn't happen, right? */
160 cerr = CSSMERR_CSP_INTERNAL_ERROR; break;
161 default:
162 break;
163 }
164 if(cerr != CSSM_OK) {
165 CssmError::throwMe(cerr);
166 }
167
168 /* now the lib-specific ones */
169 switch(lib) {
170 case ERR_R_BN_LIB:
171 /* all indicate serious internal error...right? */
172 cerr = CSSMERR_CSP_INTERNAL_ERROR; break;
173 case ERR_R_RSA_LIB:
174 switch(reason) {
175 case RSA_R_ALGORITHM_MISMATCH:
176 cerr = CSSMERR_CSP_ALGID_MISMATCH; break;
177 case RSA_R_BAD_SIGNATURE:
178 cerr = CSSMERR_CSP_VERIFY_FAILED; break;
179 case RSA_R_DATA_TOO_LARGE:
180 case RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE:
181 case RSA_R_DATA_TOO_SMALL:
182 case RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE:
183 case RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY:
184 cerr = CSSMERR_CSP_INPUT_LENGTH_ERROR; break;
185 case RSA_R_KEY_SIZE_TOO_SMALL:
186 cerr = CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH; break;
187 case RSA_R_PADDING_CHECK_FAILED:
188 case RSA_R_BLOCK_TYPE_IS_NOT_01:
189 case RSA_R_BLOCK_TYPE_IS_NOT_02:
190 case RSA_R_DATA_GREATER_THAN_MOD_LEN:
191 case RSA_R_BAD_PAD_BYTE_COUNT:
192 cerr = CSSMERR_CSP_INVALID_DATA; break;
193 case RSA_R_RSA_OPERATIONS_NOT_SUPPORTED:
194 cerr = CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED; break;
195 case RSA_R_UNKNOWN_ALGORITHM_TYPE:
196 cerr = CSSMERR_CSP_INVALID_ALGORITHM; break;
197 case RSA_R_WRONG_SIGNATURE_LENGTH:
198 cerr = CSSMERR_CSP_VERIFY_FAILED; break;
199 case RSA_R_SSLV3_ROLLBACK_ATTACK:
200 cerr = CSSMERR_CSP_APPLE_SSLv2_ROLLBACK; break;
201 default:
202 cerr = CSSMERR_CSP_INTERNAL_ERROR; break;
203 }
204 break;
205 case ERR_R_DSA_LIB:
206 switch(reason) {
207 case DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE:
208 cerr = CSSMERR_CSP_INPUT_LENGTH_ERROR; break;
209 default:
210 cerr = CSSMERR_CSP_INTERNAL_ERROR; break;
211 }
212 break;
213 case ERR_R_DH_LIB:
214 /* actually none of the DH errors make sense at the CDSA level */
215 cerr = CSSMERR_CSP_INTERNAL_ERROR;
216 break;
217 default:
218 cerr = CSSMERR_CSP_INTERNAL_ERROR; break;
219 }
220 CssmError::throwMe(cerr);
221 }
222
223 /*
224 * given an openssl-style error, throw appropriate CssmError.
225 */
226 void throwOpensslErr(int irtn)
227 {
228 /* FIXME */
229 CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR);
230 }
231