1/* 2 * $Id: openssl_missing.c 32230 2011-06-26 01:32:03Z emboss $ 3 * 'OpenSSL for Ruby' project 4 * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> 5 * All rights reserved. 6 */ 7/* 8 * This program is licenced under the same licence as Ruby. 9 * (See the file 'LICENCE'.) 10 */ 11#include RUBY_EXTCONF_H 12 13#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ST_ENGINE) 14# include <openssl/engine.h> 15#endif 16#include <openssl/x509_vfy.h> 17 18#if !defined(OPENSSL_NO_HMAC) 19#include <string.h> /* memcpy() */ 20#include <openssl/hmac.h> 21 22#include "openssl_missing.h" 23 24#if !defined(HAVE_HMAC_CTX_COPY) 25void 26HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in) 27{ 28 if (!out || !in) return; 29 memcpy(out, in, sizeof(HMAC_CTX)); 30 31 EVP_MD_CTX_copy(&out->md_ctx, &in->md_ctx); 32 EVP_MD_CTX_copy(&out->i_ctx, &in->i_ctx); 33 EVP_MD_CTX_copy(&out->o_ctx, &in->o_ctx); 34} 35#endif /* HAVE_HMAC_CTX_COPY */ 36#endif /* NO_HMAC */ 37 38#if !defined(HAVE_X509_STORE_SET_EX_DATA) 39int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data) 40{ 41 return CRYPTO_set_ex_data(&str->ex_data, idx, data); 42} 43#endif 44 45#if !defined(HAVE_X509_STORE_GET_EX_DATA) 46void *X509_STORE_get_ex_data(X509_STORE *str, int idx) 47{ 48 return CRYPTO_get_ex_data(&str->ex_data, idx); 49} 50#endif 51 52#if !defined(HAVE_EVP_MD_CTX_CREATE) 53EVP_MD_CTX * 54EVP_MD_CTX_create(void) 55{ 56 EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX)); 57 if (!ctx) return NULL; 58 59 memset(ctx, 0, sizeof(EVP_MD_CTX)); 60 61 return ctx; 62} 63#endif 64 65#if !defined(HAVE_EVP_MD_CTX_CLEANUP) 66int 67EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) 68{ 69 /* FIXME!!! */ 70 memset(ctx, 0, sizeof(EVP_MD_CTX)); 71 72 return 1; 73} 74#endif 75 76#if !defined(HAVE_EVP_MD_CTX_DESTROY) 77void 78EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) 79{ 80 EVP_MD_CTX_cleanup(ctx); 81 OPENSSL_free(ctx); 82} 83#endif 84 85#if !defined(HAVE_EVP_MD_CTX_INIT) 86void 87EVP_MD_CTX_init(EVP_MD_CTX *ctx) 88{ 89 memset(ctx, 0, sizeof(EVP_MD_CTX)); 90} 91#endif 92 93#if !defined(HAVE_HMAC_CTX_INIT) 94void 95HMAC_CTX_init(HMAC_CTX *ctx) 96{ 97 EVP_MD_CTX_init(&ctx->i_ctx); 98 EVP_MD_CTX_init(&ctx->o_ctx); 99 EVP_MD_CTX_init(&ctx->md_ctx); 100} 101#endif 102 103#if !defined(HAVE_HMAC_CTX_CLEANUP) 104void 105HMAC_CTX_cleanup(HMAC_CTX *ctx) 106{ 107 EVP_MD_CTX_cleanup(&ctx->i_ctx); 108 EVP_MD_CTX_cleanup(&ctx->o_ctx); 109 EVP_MD_CTX_cleanup(&ctx->md_ctx); 110 memset(ctx, 0, sizeof(HMAC_CTX)); 111} 112#endif 113 114#if !defined(HAVE_EVP_CIPHER_CTX_COPY) 115/* 116 * this function does not exist in OpenSSL yet... or ever?. 117 * a future version may break this function. 118 * tested on 0.9.7d. 119 */ 120int 121EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in) 122{ 123 memcpy(out, in, sizeof(EVP_CIPHER_CTX)); 124 125#if defined(HAVE_ENGINE_ADD) && defined(HAVE_ST_ENGINE) 126 if (in->engine) ENGINE_add(out->engine); 127 if (in->cipher_data) { 128 out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); 129 memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); 130 } 131#endif 132 133 return 1; 134} 135#endif 136 137#if !defined(HAVE_X509_CRL_SET_VERSION) 138int 139X509_CRL_set_version(X509_CRL *x, long version) 140{ 141 if (x == NULL || x->crl == NULL) return 0; 142 if (x->crl->version == NULL) { 143 x->crl->version = M_ASN1_INTEGER_new(); 144 if (x->crl->version == NULL) return 0; 145 } 146 return ASN1_INTEGER_set(x->crl->version, version); 147} 148#endif 149 150#if !defined(HAVE_X509_CRL_SET_ISSUER_NAME) 151int 152X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) 153{ 154 if (x == NULL || x->crl == NULL) return 0; 155 return X509_NAME_set(&x->crl->issuer, name); 156} 157#endif 158 159#if !defined(HAVE_X509_CRL_SORT) 160int 161X509_CRL_sort(X509_CRL *c) 162{ 163 int i; 164 X509_REVOKED *r; 165 /* sort the data so it will be written in serial 166 * number order */ 167 sk_X509_REVOKED_sort(c->crl->revoked); 168 for (i=0; i<sk_X509_REVOKED_num(c->crl->revoked); i++) { 169 r=sk_X509_REVOKED_value(c->crl->revoked, i); 170 r->sequence=i; 171 } 172 return 1; 173} 174#endif 175 176#if !defined(HAVE_X509_CRL_ADD0_REVOKED) 177static int 178OSSL_X509_REVOKED_cmp(const X509_REVOKED * const *a, const X509_REVOKED * const *b) 179{ 180 return(ASN1_STRING_cmp( 181 (ASN1_STRING *)(*a)->serialNumber, 182 (ASN1_STRING *)(*b)->serialNumber)); 183} 184 185int 186X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) 187{ 188 X509_CRL_INFO *inf; 189 190 inf = crl->crl; 191 if (!inf->revoked) 192 inf->revoked = sk_X509_REVOKED_new(OSSL_X509_REVOKED_cmp); 193 if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) 194 return 0; 195 return 1; 196} 197#endif 198 199#if !defined(HAVE_BN_MOD_SQR) 200int 201BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) 202{ 203 if (!BN_sqr(r, (BIGNUM*)a, ctx)) return 0; 204 return BN_mod(r, r, m, ctx); 205} 206#endif 207 208#if !defined(HAVE_BN_MOD_ADD) || !defined(HAVE_BN_MOD_SUB) 209int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) 210{ 211 if (!BN_mod(r,m,d,ctx)) return 0; 212 if (!r->neg) return 1; 213 return (d->neg ? BN_sub : BN_add)(r, r, d); 214} 215#endif 216 217#if !defined(HAVE_BN_MOD_ADD) 218int 219BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) 220{ 221 if (!BN_add(r, a, b)) return 0; 222 return BN_nnmod(r, r, m, ctx); 223} 224#endif 225 226#if !defined(HAVE_BN_MOD_SUB) 227int 228BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) 229{ 230 if (!BN_sub(r, a, b)) return 0; 231 return BN_nnmod(r, r, m, ctx); 232} 233#endif 234 235#if !defined(HAVE_BN_RAND_RANGE) || !defined(HAVE_BN_PSEUDO_RAND_RANGE) 236static int 237bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range) 238{ 239 int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand; 240 int n; 241 242 if (range->neg || BN_is_zero(range)) return 0; 243 244 n = BN_num_bits(range); 245 246 if (n == 1) { 247 if (!BN_zero(r)) return 0; 248 } else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) { 249 do { 250 if (!bn_rand(r, n + 1, -1, 0)) return 0; 251 if (BN_cmp(r ,range) >= 0) { 252 if (!BN_sub(r, r, range)) return 0; 253 if (BN_cmp(r, range) >= 0) 254 if (!BN_sub(r, r, range)) return 0; 255 } 256 } while (BN_cmp(r, range) >= 0); 257 } else { 258 do { 259 if (!bn_rand(r, n, -1, 0)) return 0; 260 } while (BN_cmp(r, range) >= 0); 261 } 262 263 return 1; 264} 265#endif 266 267#if !defined(HAVE_BN_RAND_RANGE) 268int 269BN_rand_range(BIGNUM *r, BIGNUM *range) 270{ 271 return bn_rand_range(0, r, range); 272} 273#endif 274 275#if !defined(HAVE_BN_PSEUDO_RAND_RANGE) 276int 277BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range) 278{ 279 return bn_rand_range(1, r, range); 280} 281#endif 282 283#if !defined(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE) 284#define OPENSSL_CONF "openssl.cnf" 285char * 286CONF_get1_default_config_file(void) 287{ 288 char *file; 289 int len; 290 291 file = getenv("OPENSSL_CONF"); 292 if (file) return BUF_strdup(file); 293 len = strlen(X509_get_default_cert_area()); 294#ifndef OPENSSL_SYS_VMS 295 len++; 296#endif 297 len += strlen(OPENSSL_CONF); 298 file = OPENSSL_malloc(len + 1); 299 if (!file) return NULL; 300 strcpy(file,X509_get_default_cert_area()); 301#ifndef OPENSSL_SYS_VMS 302 strcat(file,"/"); 303#endif 304 strcat(file,OPENSSL_CONF); 305 306 return file; 307} 308#endif 309 310#if !defined(HAVE_PEM_DEF_CALLBACK) 311#define OSSL_PASS_MIN_LENGTH 4 312int 313PEM_def_callback(char *buf, int num, int w, void *key) 314{ 315 int i,j; 316 const char *prompt; 317 318 if (key) { 319 i = strlen(key); 320 i = (i > num) ? num : i; 321 memcpy(buf, key, i); 322 return i; 323 } 324 325 prompt = EVP_get_pw_prompt(); 326 if (prompt == NULL) prompt = "Enter PEM pass phrase:"; 327 for (;;) { 328 i = EVP_read_pw_string(buf, num, prompt, w); 329 if (i != 0) { 330 memset(buf, 0, (unsigned int)num); 331 return(-1); 332 } 333 j = strlen(buf); 334 if (j < OSSL_PASS_MIN_LENGTH) { 335 fprintf(stderr, 336 "phrase is too short, needs to be at least %d chars\n", 337 OSSL_PASS_MIN_LENGTH); 338 } 339 else break; 340 } 341 return j; 342} 343#endif 344 345#if !defined(HAVE_ASN1_PUT_EOC) 346int 347ASN1_put_eoc(unsigned char **pp) 348{ 349 unsigned char *p = *pp; 350 *p++ = 0; 351 *p++ = 0; 352 *pp = p; 353 return 2; 354} 355#endif 356 357