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 * opensslUtils.h - Support for ssleay-derived crypto modules 21 */ 22 23#include <openssl/rand.h> 24#include <openssl/crypto.h> 25#include <openssl/err.h> 26#include <openssl/sha.h> 27#include <openssl/rsa.h> 28#include <openssl/dsa.h> 29#include <openssl/dh.h> 30#include <openssl/err.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...) secdebug("sslUtils", ## args) 39 40openSslException::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 55static int randDex = 1; 56 57int 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 73int RAND_pseudo_bytes(unsigned char *buf,int num) 74{ 75 return RAND_bytes(buf, num); 76} 77 78void 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 */ 88int CRYPTO_mem_ctrl(int mode) 89{ 90 return 0; 91} 92 93/* Clear openssl error stack. */ 94void 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 */ 103unsigned 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 */ 125unsigned 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 135void 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 */ 226void throwOpensslErr(int irtn) 227{ 228 /* FIXME */ 229 CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); 230} 231 232