#include "config.h"
-#ifdef __APPLE__
#define COMMON_DIGEST_FOR_OPENSSL 1
-#endif
#include <sys/types.h>
#include <sys/param.h>
#include <limits.h>
#include <string.h>
+#ifdef HAVE_OPENSSL
/* get openssl/ssleay version number */
#include <openssl/opensslv.h>
#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090602fL)
#error OpenSSL version 0.9.6 or later required.
#endif
-
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <openssl/bn.h>
#include <openssl/dh.h>
-#ifdef __APPLE__
-#include <CommonCrypto/CommonDigest.h>
-#include <CommonCrypto/CommonHMAC.h>
-#include <CommonCrypto/CommonCryptor.h>
-#else
-#include <openssl/md5.h>
-#include <openssl/sha.h>
-#include <openssl/hmac.h>
-#endif
#include <openssl/des.h>
#include <openssl/crypto.h>
#ifdef HAVE_OPENSSL_ENGINE_H
#include <openssl/engine.h>
#endif
-#include <openssl/blowfish.h>
-#include <openssl/cast.h>
#include <openssl/err.h>
-#ifdef HAVE_OPENSSL_RC5_H
-#include <openssl/rc5.h>
-#endif
-#ifdef HAVE_OPENSSL_IDEA_H
-#include <openssl/idea.h>
-#endif
-#if defined(HAVE_OPENSSL_AES_H)
-#include <openssl/aes.h>
-#elif defined(HAVE_OPENSSL_RIJNDAEL_H)
-#include <openssl/rijndael.h>
-#else
-#include "crypto/rijndael/rijndael-api-fst.h"
-#endif
-#ifdef WITH_SHA2
-#ifndef __APPLE__
-#ifdef HAVE_OPENSSL_SHA2_H
-#include <openssl/sha2.h>
-#endif
-#endif
-#endif
+#else /* HAVE_OPENSSL */
+#include <Security/SecDH.h>
+#include <Security/SecRandom.h>
+#endif /* HAVE_OPENSSL */
+
+#include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonHMAC.h>
+#include <CommonCrypto/CommonCryptor.h>
+#ifdef HAVE_OPENSSL
/* 0.9.7 stuff? */
#if OPENSSL_VERSION_NUMBER < 0x0090700fL
typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
#define USE_NEW_DES_API
#endif
-#define OpenSSL_BUG() do { plog(LLV_ERROR, LOCATION, NULL, "OpenSSL function failed\n"); } while(0)
+#define OpenSSL_BUG() do { plog(ASL_LEVEL_ERR, "OpenSSL function failed\n"); } while(0)
+#endif
+#include "crypto_openssl.h"
#include "var.h"
#include "misc.h"
#include "vmbuf.h"
#include "plog.h"
-#include "crypto_openssl.h"
#include "debug.h"
#include "gcmalloc.h"
* necessary for SSLeay/OpenSSL portability. It sucks.
*/
-static int cb_check_cert_local __P((int, X509_STORE_CTX *));
-static int cb_check_cert_remote __P((int, X509_STORE_CTX *));
-static X509 *mem2x509 __P((vchar_t *));
-
-#ifdef __APPLE__
-static caddr_t eay_hmac_init __P((vchar_t *, CCHmacAlgorithm));
-#else
-static caddr_t eay_hmac_init __P((vchar_t *, const EVP_MD *));
+#ifdef HAVE_OPENSSL
+static X509 *mem2x509(vchar_t *);
#endif
+static caddr_t eay_hmac_init (vchar_t *, CCHmacAlgorithm);
-/* X509 Certificate */
-/*
- * convert the string of the subject name into DER
- * e.g. str = "C=JP, ST=Kanagawa";
- */
-vchar_t *
-eay_str2asn1dn(str, len)
- const char *str;
- int len;
-{
- X509_NAME *name;
- char *buf;
- char *field, *value;
- int i, j;
- vchar_t *ret = NULL;
- caddr_t p;
-
- if (len == -1)
- len = strlen(str);
-
- buf = racoon_malloc(len + 1);
- if (!buf) {
- plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n");
- return NULL;
- }
- memcpy(buf, str, len);
-
- name = X509_NAME_new();
-
- field = &buf[0];
- value = NULL;
- for (i = 0; i < len; i++) {
- if (!value && buf[i] == '=') {
- buf[i] = '\0';
- value = &buf[i + 1];
- continue;
- } else if (buf[i] == ',' || buf[i] == '/') {
- buf[i] = '\0';
-
- plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n",
- field, value);
-
- if (!value) goto err;
- if (!X509_NAME_add_entry_by_txt(name, field,
- (value[0] == '*' && value[1] == 0) ?
- V_ASN1_PRINTABLESTRING : MBSTRING_ASC,
- (unsigned char *) value, -1, -1, 0)) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Invalid DN field: %s=%s\n",
- field, value);
- plog(LLV_ERROR, LOCATION, NULL,
- "%s\n", eay_strerror());
- goto err;
- }
- for (j = i + 1; j < len; j++) {
- if (buf[j] != ' ')
- break;
- }
- field = &buf[j];
- value = NULL;
- continue;
- }
- }
- buf[len] = '\0';
-
- plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n",
- field, value);
-
- if (!value) goto err;
- if (!X509_NAME_add_entry_by_txt(name, field,
- (value[0] == '*' && value[1] == 0) ?
- V_ASN1_PRINTABLESTRING : MBSTRING_ASC,
- (unsigned char *) value, -1, -1, 0)) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Invalid DN field: %s=%s\n",
- field, value);
- plog(LLV_ERROR, LOCATION, NULL,
- "%s\n", eay_strerror());
- goto err;
- }
-
- i = i2d_X509_NAME(name, NULL);
- if (!i)
- goto err;
- ret = vmalloc(i);
- if (!ret)
- goto err;
- p = ret->v;
- i = i2d_X509_NAME(name, (void *)&p);
- if (!i)
- goto err;
-
- return ret;
-
- err:
- if (buf)
- racoon_free(buf);
- if (name)
- X509_NAME_free(name);
- if (ret)
- vfree(ret);
- return NULL;
-}
-
-/*
- * convert the hex string of the subject name into DER
- */
-vchar_t *
-eay_hex2asn1dn(const char *hex, int len)
-{
- BIGNUM *bn = BN_new();
- char *binbuf;
- size_t binlen;
- vchar_t *ret = NULL;
-
- if (len == -1)
- len = strlen(hex);
-
- if (BN_hex2bn(&bn, hex) != len) {
- plog(LLV_ERROR, LOCATION, NULL,
- "conversion of Hex-encoded ASN1 string to binary failed: %s\n",
- eay_strerror());
- goto out;
- }
-
- binlen = BN_num_bytes(bn);
- ret = vmalloc(binlen);
- if (!ret) {
- plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n");
- return NULL;
- }
- binbuf = ret->v;
-
- BN_bn2bin(bn, (unsigned char *) binbuf);
-out:
- BN_free(bn);
-
- return ret;
-}
+#ifdef HAVE_OPENSSL
/*
* The following are derived from code in crypto/x509/x509_cmp.c
return i;
}
-/*
- * this functions is derived from apps/verify.c in OpenSSL0.9.5
- */
-int
-eay_check_x509cert(cert, CApath, CAfile, local)
- vchar_t *cert;
- char *CApath;
- char *CAfile;
- int local;
-{
- X509_STORE *cert_ctx = NULL;
- X509_LOOKUP *lookup = NULL;
- X509 *x509 = NULL;
- X509_STORE_CTX *csc;
- int error = -1;
-
- cert_ctx = X509_STORE_new();
- if (cert_ctx == NULL)
- goto end;
-
- if (local)
- X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_local);
- else
- X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_remote);
-
- lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
- if (lookup == NULL)
- goto end;
-
- X509_LOOKUP_load_file(lookup, CAfile,
- (CAfile == NULL) ? X509_FILETYPE_DEFAULT : X509_FILETYPE_PEM);
-
- lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
- if (lookup == NULL)
- goto end;
- error = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM);
- if(!error) {
- error = -1;
- goto end;
- }
- error = -1; /* initialized */
-
- /* read the certificate to be verified */
- x509 = mem2x509(cert);
- if (x509 == NULL)
- goto end;
-
- csc = X509_STORE_CTX_new();
- if (csc == NULL)
- goto end;
- X509_STORE_CTX_init(csc, cert_ctx, x509, NULL);
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
- X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK);
- X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK_ALL);
-#endif
- error = X509_verify_cert(csc);
- X509_STORE_CTX_free(csc);
-
- /*
- * if x509_verify_cert() is successful then the value of error is
- * set non-zero.
- */
- error = error ? 0 : -1;
-
-end:
- if (error)
- plog(LLV_WARNING, LOCATION, NULL,"%s\n", eay_strerror());
- if (cert_ctx != NULL)
- X509_STORE_free(cert_ctx);
- if (x509 != NULL)
- X509_free(x509);
-
- return(error);
-}
-
-/*
- * callback function for verifing certificate.
- * this function is derived from cb() in openssl/apps/s_server.c
- */
-static int
-cb_check_cert_local(ok, ctx)
- int ok;
- X509_STORE_CTX *ctx;
-{
- char buf[256];
- int log_tag;
-
- if (!ok) {
- X509_NAME_oneline(
- X509_get_subject_name(ctx->current_cert),
- buf,
- 256);
- /*
- * since we are just checking the certificates, it is
- * ok if they are self signed. But we should still warn
- * the user.
- */
- switch (ctx->error) {
- case X509_V_ERR_CERT_HAS_EXPIRED:
- case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
- case X509_V_ERR_INVALID_CA:
- case X509_V_ERR_PATH_LENGTH_EXCEEDED:
- case X509_V_ERR_INVALID_PURPOSE:
- case X509_V_ERR_UNABLE_TO_GET_CRL:
- ok = 1;
- log_tag = LLV_WARNING;
- break;
- default:
- log_tag = LLV_ERROR;
- }
- plog(log_tag, LOCATION, NULL,
- "%s(%d) at depth:%d SubjectName:%s\n",
- X509_verify_cert_error_string(ctx->error),
- ctx->error,
- ctx->error_depth,
- buf);
- }
- ERR_clear_error();
-
- return ok;
-}
-
-/*
- * callback function for verifing remote certificates.
- * this function is derived from cb() in openssl/apps/s_server.c
- */
-static int
-cb_check_cert_remote(ok, ctx)
- int ok;
- X509_STORE_CTX *ctx;
-{
- char buf[256];
- int log_tag;
-
- if (!ok) {
- X509_NAME_oneline(
- X509_get_subject_name(ctx->current_cert),
- buf,
- 256);
- switch (ctx->error) {
- case X509_V_ERR_UNABLE_TO_GET_CRL:
- ok = 1;
- log_tag = LLV_WARNING;
- break;
- default:
- log_tag = LLV_ERROR;
- }
- plog(log_tag, LOCATION, NULL,
- "%s(%d) at depth:%d SubjectName:%s\n",
- X509_verify_cert_error_string(ctx->error),
- ctx->error,
- ctx->error_depth,
- buf);
- }
- ERR_clear_error();
-
- return ok;
-}
-
-/*
- * get a subjectAltName from X509 certificate.
- */
-vchar_t *
-eay_get_x509asn1subjectname(cert)
- vchar_t *cert;
-{
- X509 *x509 = NULL;
- u_char *bp;
- vchar_t *name = NULL;
- int len;
-
- bp = (unsigned char *) cert->v;
-
- x509 = mem2x509(cert);
- if (x509 == NULL)
- goto error;
-
- /* get the length of the name */
- len = i2d_X509_NAME(x509->cert_info->subject, NULL);
- name = vmalloc(len);
- if (!name)
- goto error;
- /* get the name */
- bp = (unsigned char *) name->v;
- len = i2d_X509_NAME(x509->cert_info->subject, &bp);
-
- X509_free(x509);
-
- return name;
-
-error:
- plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
-
- if (name != NULL)
- vfree(name);
-
- if (x509 != NULL)
- X509_free(x509);
-
- return NULL;
-}
-
-#ifdef __APPLE__
-
/*
* Get the common name from a cert
*/
commonName = vmalloc(EAY_MAX_CN_LEN);
if (commonName == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "no memory\n");
+ plog(ASL_LEVEL_ERR, "no memory\n");
return NULL;
}
/* make sure the data is terminated by '\0'. */
if (gen->d.ia5->data[gen->d.ia5->length] != '\0') {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"data is not terminated by 0.");
hexdump(gen->d.ia5->data, gen->d.ia5->length + 1);
goto end;
*altname = NULL;
}
#ifndef EAYDEBUG
- plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
+ plog(ASL_LEVEL_ERR, "%s\n", eay_strerror());
#else
printf("%s\n", eay_strerror());
#endif
return error;
}
-#else /* __APPLE__ */
-
-/*
- * get the subjectAltName from X509 certificate.
- * the name must be terminated by '\0'.
- */
-int
-eay_get_x509subjectaltname(cert, altname, type, pos)
- vchar_t *cert;
- char **altname;
- int *type;
- int pos;
-{
- X509 *x509 = NULL;
- GENERAL_NAMES *gens = NULL;
- GENERAL_NAME *gen;
- int len;
- int error = -1;
-
- *altname = NULL;
- *type = GENT_OTHERNAME;
-
- x509 = mem2x509(cert);
- if (x509 == NULL)
- goto end;
-
- gens = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
- if (gens == NULL)
- goto end;
-
- /* there is no data at "pos" */
- if (pos > sk_GENERAL_NAME_num(gens))
- goto end;
-
- gen = sk_GENERAL_NAME_value(gens, pos - 1);
-
- /* read DNSName / Email */
- if (gen->type == GEN_DNS ||
- gen->type == GEN_EMAIL ||
- gen->type == GEN_URI )
- {
- /* make sure if the data is terminated by '\0'. */
- if (gen->d.ia5->data[gen->d.ia5->length] != '\0')
- {
- plog(LLV_ERROR, LOCATION, NULL,
- "data is not terminated by NUL.");
- hexdump(gen->d.ia5->data, gen->d.ia5->length + 1);
- goto end;
- }
-
- len = gen->d.ia5->length + 1;
- *altname = racoon_malloc(len);
- if (!*altname)
- goto end;
-
- strlcpy(*altname, (char *) gen->d.ia5->data, len);
- *type = gen->type;
- error = 0;
- }
- /* read IP address */
- else if (gen->type == GEN_IPADD)
- {
- unsigned char p[5], *ip;
- const int maxaltnamelen = 20;
- ip = p;
-
- /* only support IPv4 */
- if (gen->d.ip->length != 4)
- goto end;
-
- /* convert Octet String to String
- * XXX ???????
- */
- /*i2d_ASN1_OCTET_STRING(gen->d.ip,&ip);*/
- ip = gen->d.ip->data;
-
- /* XXX Magic, enough for an IPv4 address
- */
- *altname = racoon_malloc(maxaltnamelen);
- if (!*altname)
- goto end;
-
- snprintf(*altname, maxaltnamelen, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
- *type = gen->type;
- error = 0;
- }
- /* XXX other possible types ?
- * For now, error will be -1 if unsupported type
- */
-
-end:
- if (error) {
- if (*altname) {
- racoon_free(*altname);
- *altname = NULL;
- }
- plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
- }
- if (x509)
- X509_free(x509);
- if (gens)
- /* free the whole stack. */
- sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
-
- return error;
-}
-
-#endif
-
-/*
- * decode a X509 certificate and make a readable text terminated '\n'.
- * return the buffer allocated, so must free it later.
- */
-char *
-eay_get_x509text(cert)
- vchar_t *cert;
-{
- X509 *x509 = NULL;
- BIO *bio = NULL;
- char *text = NULL;
- u_char *bp = NULL;
- int len = 0;
- int error = -1;
-
- x509 = mem2x509(cert);
- if (x509 == NULL)
- goto end;
-
- bio = BIO_new(BIO_s_mem());
- if (bio == NULL)
- goto end;
-
- error = X509_print(bio, x509);
- if (error != 1) {
- error = -1;
- goto end;
- }
-
- len = BIO_get_mem_data(bio, &bp);
- text = racoon_malloc(len + 1);
- if (text == NULL)
- goto end;
- memcpy(text, bp, len);
- text[len] = '\0';
-
- error = 0;
-
- end:
- if (error) {
- if (text) {
- racoon_free(text);
- text = NULL;
- }
- plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
- }
- if (bio)
- BIO_free(bio);
- if (x509)
- X509_free(x509);
-
- return text;
-}
/* get X509 structure from buffer. */
static X509 *
}
/*
- * get a X509 certificate from local file.
- * a certificate must be PEM format.
- * Input:
- * path to a certificate.
- * Output:
- * NULL if error occured
- * other is the cert.
+ * get error string
+ * MUST load ERR_load_crypto_strings() first.
*/
-vchar_t *
-eay_get_x509cert(path)
- char *path;
+char *
+eay_strerror()
{
- FILE *fp;
- X509 *x509;
- vchar_t *cert;
- u_char *bp;
- int len;
- int error;
+ static char ebuf[512];
+ int len = 0, n;
+ unsigned long l;
+ char buf[200];
+ const char *file, *data;
+ int line, flags;
+ unsigned long es;
- /* Read private key */
- fp = fopen(path, "r");
- if (fp == NULL)
- return NULL;
- x509 = PEM_read_X509(fp, NULL, NULL, NULL);
- fclose (fp);
-
- if (x509 == NULL)
- return NULL;
-
- len = i2d_X509(x509, NULL);
- cert = vmalloc(len);
- if (cert == NULL) {
- X509_free(x509);
- return NULL;
- }
- bp = (unsigned char *) cert->v;
- error = i2d_X509(x509, &bp);
- X509_free(x509);
-
- if (error == 0) {
- vfree(cert);
- return NULL;
- }
-
- return cert;
-}
-
-/*
- * check a X509 signature
- * XXX: to be get hash type from my cert ?
- * to be handled EVP_dss().
- * OUT: return -1 when error.
- * 0
- */
-int
-eay_check_x509sign(source, sig, cert)
- vchar_t *source;
- vchar_t *sig;
- vchar_t *cert;
-{
- X509 *x509;
- u_char *bp;
- EVP_PKEY *evp;
- int res;
-
- bp = (unsigned char *) cert->v;
-
- x509 = d2i_X509(NULL, (void *)&bp, cert->l);
- if (x509 == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "d2i_X509(): %s\n", eay_strerror());
- return -1;
- }
-
- evp = X509_get_pubkey(x509);
- if (! evp) {
- plog(LLV_ERROR, LOCATION, NULL, "X509_get_pubkey(): %s\n", eay_strerror());
- X509_free(x509);
- return -1;
- }
-
- res = eay_rsa_verify(source, sig, evp->pkey.rsa);
-
- EVP_PKEY_free(evp);
- X509_free(x509);
-
- return res;
-}
-
-/*
- * check RSA signature
- * OUT: return -1 when error.
- * 0 on success
- */
-int
-eay_check_rsasign(source, sig, rsa)
- vchar_t *source;
- vchar_t *sig;
- RSA *rsa;
-{
- return eay_rsa_verify(source, sig, rsa);
-}
-
-/*
- * get PKCS#1 Private Key of PEM format from local file.
- */
-vchar_t *
-eay_get_pkcs1privkey(path)
- char *path;
-{
- FILE *fp;
- EVP_PKEY *evp = NULL;
- vchar_t *pkey = NULL;
- u_char *bp;
- int pkeylen;
- int error = -1;
-
- /* Read private key */
- fp = fopen(path, "r");
- if (fp == NULL)
- return NULL;
-
- evp = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
-
- fclose (fp);
-
- if (evp == NULL)
- return NULL;
-
- pkeylen = i2d_PrivateKey(evp, NULL);
- if (pkeylen == 0)
- goto end;
- pkey = vmalloc(pkeylen);
- if (pkey == NULL)
- goto end;
- bp = (unsigned char *) pkey->v;
- pkeylen = i2d_PrivateKey(evp, &bp);
- if (pkeylen == 0)
- goto end;
-
- error = 0;
-
-end:
- if (evp != NULL)
- EVP_PKEY_free(evp);
- if (error != 0 && pkey != NULL) {
- vfree(pkey);
- pkey = NULL;
- }
-
- return pkey;
-}
-
-/*
- * get PKCS#1 Public Key of PEM format from local file.
- */
-vchar_t *
-eay_get_pkcs1pubkey(path)
- char *path;
-{
- FILE *fp;
- EVP_PKEY *evp = NULL;
- vchar_t *pkey = NULL;
- X509 *x509 = NULL;
- u_char *bp;
- int pkeylen;
- int error = -1;
-
- /* Read private key */
- fp = fopen(path, "r");
- if (fp == NULL)
- return NULL;
-
- x509 = PEM_read_X509(fp, NULL, NULL, NULL);
-
- fclose (fp);
-
- if (x509 == NULL)
- return NULL;
-
- /* Get public key - eay */
- evp = X509_get_pubkey(x509);
- if (evp == NULL)
- return NULL;
-
- pkeylen = i2d_PublicKey(evp, NULL);
- if (pkeylen == 0)
- goto end;
- pkey = vmalloc(pkeylen);
- if (pkey == NULL)
- goto end;
- bp = (unsigned char *) pkey->v;
- pkeylen = i2d_PublicKey(evp, &bp);
- if (pkeylen == 0)
- goto end;
-
- error = 0;
-end:
- if (evp != NULL)
- EVP_PKEY_free(evp);
- if (error != 0 && pkey != NULL) {
- vfree(pkey);
- pkey = NULL;
- }
-
- return pkey;
-}
-
-vchar_t *
-eay_get_x509sign(src, privkey)
- vchar_t *src, *privkey;
-{
- EVP_PKEY *evp;
- u_char *bp = (unsigned char *) privkey->v;
- vchar_t *sig = NULL;
- int len;
- int pad = RSA_PKCS1_PADDING;
-
- /* XXX to be handled EVP_PKEY_DSA */
- evp = d2i_PrivateKey(EVP_PKEY_RSA, NULL, (void *)&bp, privkey->l);
- if (evp == NULL)
- return NULL;
-
- sig = eay_rsa_sign(src, evp->pkey.rsa);
-
- EVP_PKEY_free(evp);
-
- return sig;
-}
-
-vchar_t *
-eay_get_rsasign(src, rsa)
- vchar_t *src;
- RSA *rsa;
-{
- return eay_rsa_sign(src, rsa);
-}
-
-vchar_t *
-eay_rsa_sign(vchar_t *src, RSA *rsa)
-{
- int len;
- vchar_t *sig = NULL;
- int pad = RSA_PKCS1_PADDING;
-
- len = RSA_size(rsa);
-
- sig = vmalloc(len);
- if (sig == NULL)
- return NULL;
-
- len = RSA_private_encrypt(src->l, (unsigned char *) src->v,
- (unsigned char *) sig->v, rsa, pad);
-
- if (len == 0 || len != sig->l) {
- vfree(sig);
- sig = NULL;
- }
-
- return sig;
-}
-
-int
-eay_rsa_verify(src, sig, rsa)
- vchar_t *src, *sig;
- RSA *rsa;
-{
- vchar_t *xbuf = NULL;
- int pad = RSA_PKCS1_PADDING;
- int len = 0;
- int error;
-
- len = RSA_size(rsa);
- xbuf = vmalloc(len);
- if (xbuf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
- return -1;
- }
-
- len = RSA_public_decrypt(sig->l, (unsigned char *) sig->v,
- (unsigned char *) xbuf->v, rsa, pad);
- if (len == 0 || len != src->l) {
- plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
- vfree(xbuf);
- return -1;
- }
-
- error = memcmp(src->v, xbuf->v, src->l);
- vfree(xbuf);
- if (error != 0)
- return -1;
-
- return 0;
-}
-
-/*
- * get error string
- * MUST load ERR_load_crypto_strings() first.
- */
-char *
-eay_strerror()
-{
- static char ebuf[512];
- int len = 0, n;
- unsigned long l;
- char buf[200];
- const char *file, *data;
- int line, flags;
- unsigned long es;
-
- es = CRYPTO_thread_id();
+ es = CRYPTO_thread_id();
while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0){
n = snprintf(ebuf + len, sizeof(ebuf) - len,
return ebuf;
}
-vchar_t *
-evp_crypt(vchar_t *data, vchar_t *key, vchar_t *iv, const EVP_CIPHER *e, int enc)
-{
- vchar_t *res;
- EVP_CIPHER_CTX ctx;
-
- if (!e)
- return NULL;
-
- if (data->l % EVP_CIPHER_block_size(e))
- return NULL;
-
- if ((res = vmalloc(data->l)) == NULL)
- return NULL;
-
- EVP_CIPHER_CTX_init(&ctx);
-
- switch(EVP_CIPHER_nid(e)){
- case NID_bf_cbc:
- case NID_bf_ecb:
- case NID_bf_cfb64:
- case NID_bf_ofb64:
- case NID_cast5_cbc:
- case NID_cast5_ecb:
- case NID_cast5_cfb64:
- case NID_cast5_ofb64:
- /* XXX: can we do that also for algos with a fixed key size ?
- */
- /* init context without key/iv
- */
- if (!EVP_CipherInit(&ctx, e, NULL, NULL, enc))
- {
- OpenSSL_BUG();
- vfree(res);
- return NULL;
- }
-
- /* update key size
- */
- if (!EVP_CIPHER_CTX_set_key_length(&ctx, key->l))
- {
- OpenSSL_BUG();
- vfree(res);
- return NULL;
- }
-
- /* finalize context init with desired key size
- */
- if (!EVP_CipherInit(&ctx, NULL, (u_char *) key->v,
- (u_char *) iv->v, enc))
- {
- OpenSSL_BUG();
- vfree(res);
- return NULL;
- }
- break;
- default:
- if (!EVP_CipherInit(&ctx, e, (u_char *) key->v,
- (u_char *) iv->v, enc)) {
- OpenSSL_BUG();
- vfree(res);
- return NULL;
- }
- }
-
- /* disable openssl padding */
- EVP_CIPHER_CTX_set_padding(&ctx, 0);
-
- if (!EVP_Cipher(&ctx, (u_char *) res->v, (u_char *) data->v, data->l)) {
- OpenSSL_BUG();
- vfree(res);
- return NULL;
- }
-
- EVP_CIPHER_CTX_cleanup(&ctx);
-
- return res;
-}
-
-int
-evp_weakkey(vchar_t *key, const EVP_CIPHER *e)
-{
- return 0;
-}
-
-int
-evp_keylen(int len, const EVP_CIPHER *e)
-{
- if (!e)
- return -1;
- /* EVP functions return lengths in bytes, ipsec-tools
- * uses lengths in bits, therefore conversion is required. --AK
- */
- if (len != 0 && len != (EVP_CIPHER_key_length(e) << 3))
- return -1;
-
- return EVP_CIPHER_key_length(e) << 3;
-}
+#endif /* HAVE_OPENSSL */
vchar_t *
eay_CCCrypt(CCOperation oper,
res->v, res->l, &res_len);
if (status == kCCSuccess) {
if (res->l != res_len) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"crypt %d %d length mismatch. expected: %zd. got: %zd.\n",
oper, algo, res->l, res_len);
}
return res;
} else {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"crypt %d %d error. status %d.\n",
oper, algo, (int)status);
}
eay_des_encrypt(data, key, iv)
vchar_t *data, *key, *iv;
{
-#ifdef __APPLE__
return(eay_CCCrypt(kCCEncrypt, kCCAlgorithmDES, 0 /* CBC */, data, key, iv));
-#else
- return evp_crypt(data, key, iv, EVP_des_cbc(), 1);
-#endif /* __APPLE__ */
}
vchar_t *
eay_des_decrypt(data, key, iv)
vchar_t *data, *key, *iv;
{
-#ifdef __APPLE__
return(eay_CCCrypt(kCCDecrypt, kCCAlgorithmDES, 0 /* CBC */, data, key, iv));
-#else
- return evp_crypt(data, key, iv, EVP_des_cbc(), 0);
-#endif /* __APPLE__ */
}
int
eay_des_weakkey(key)
vchar_t *key;
{
+#ifdef HAVE_OPENSSL
#ifdef USE_NEW_DES_API
return DES_is_weak_key((void *)key->v);
#else
return des_is_weak_key((void *)key->v);
#endif
+#else
+ return 0;
+#endif
}
int
eay_des_keylen(len)
int len;
{
-#ifdef __APPLE__
/* CommonCrypto return lengths in bytes, ipsec-tools
* uses lengths in bits, therefore conversion is required.
*/
return -1;
return kCCKeySizeDES << 3;
-#else
- return evp_keylen(len, EVP_des_cbc());
-#endif /* __APPLE__ */
}
-#ifdef HAVE_OPENSSL_IDEA_H
-/*
- * IDEA-CBC
- */
-vchar_t *
-eay_idea_encrypt(data, key, iv)
- vchar_t *data, *key, *iv;
-{
- vchar_t *res;
- IDEA_KEY_SCHEDULE ks;
-
- idea_set_encrypt_key(key->v, &ks);
-
- /* allocate buffer for result */
- if ((res = vmalloc(data->l)) == NULL)
- return NULL;
-
- /* decryption data */
- idea_cbc_encrypt(data->v, res->v, data->l,
- &ks, iv->v, IDEA_ENCRYPT);
-
- return res;
-}
-
-vchar_t *
-eay_idea_decrypt(data, key, iv)
- vchar_t *data, *key, *iv;
-{
- vchar_t *res;
- IDEA_KEY_SCHEDULE ks, dks;
-
- idea_set_encrypt_key(key->v, &ks);
- idea_set_decrypt_key(&ks, &dks);
-
- /* allocate buffer for result */
- if ((res = vmalloc(data->l)) == NULL)
- return NULL;
-
- /* decryption data */
- idea_cbc_encrypt(data->v, res->v, data->l,
- &dks, iv->v, IDEA_DECRYPT);
-
- return res;
-}
-
-int
-eay_idea_weakkey(key)
- vchar_t *key;
-{
- return 0; /* XXX */
-}
-
-int
-eay_idea_keylen(len)
- int len;
-{
- if (len != 0 && len != 128)
- return -1;
- return 128;
-}
-#endif
-
-/*
- * BLOWFISH-CBC
- */
-vchar_t *
-eay_bf_encrypt(data, key, iv)
- vchar_t *data, *key, *iv;
-{
- return evp_crypt(data, key, iv, EVP_bf_cbc(), 1);
-}
-
-vchar_t *
-eay_bf_decrypt(data, key, iv)
- vchar_t *data, *key, *iv;
-{
- return evp_crypt(data, key, iv, EVP_bf_cbc(), 0);
-}
-
-int
-eay_bf_weakkey(key)
- vchar_t *key;
-{
- return 0; /* XXX to be done. refer to RFC 2451 */
-}
-
-int
-eay_bf_keylen(len)
- int len;
-{
- if (len == 0)
- return 448;
- if (len < 40 || len > 448)
- return -1;
- return len;
-}
-
-#ifdef HAVE_OPENSSL_RC5_H
-/*
- * RC5-CBC
- */
-vchar_t *
-eay_rc5_encrypt(data, key, iv)
- vchar_t *data, *key, *iv;
-{
- vchar_t *res;
- RC5_32_KEY ks;
-
- /* in RFC 2451, there is information about the number of round. */
- RC5_32_set_key(&ks, key->l, key->v, 16);
-
- /* allocate buffer for result */
- if ((res = vmalloc(data->l)) == NULL)
- return NULL;
-
- /* decryption data */
- RC5_32_cbc_encrypt(data->v, res->v, data->l,
- &ks, iv->v, RC5_ENCRYPT);
-
- return res;
-}
-
-vchar_t *
-eay_rc5_decrypt(data, key, iv)
- vchar_t *data, *key, *iv;
-{
- vchar_t *res;
- RC5_32_KEY ks;
-
- /* in RFC 2451, there is information about the number of round. */
- RC5_32_set_key(&ks, key->l, key->v, 16);
-
- /* allocate buffer for result */
- if ((res = vmalloc(data->l)) == NULL)
- return NULL;
-
- /* decryption data */
- RC5_32_cbc_encrypt(data->v, res->v, data->l,
- &ks, iv->v, RC5_DECRYPT);
-
- return res;
-}
-
-int
-eay_rc5_weakkey(key)
- vchar_t *key;
-{
- return 0; /* No known weak keys when used with 16 rounds. */
-
-}
-
-int
-eay_rc5_keylen(len)
- int len;
-{
- if (len == 0)
- return 128;
- if (len < 40 || len > 2040)
- return -1;
- return len;
-}
-#endif
-
/*
* 3DES-CBC
*/
eay_3des_encrypt(data, key, iv)
vchar_t *data, *key, *iv;
{
-#ifdef __APPLE__
return(eay_CCCrypt(kCCEncrypt, kCCAlgorithm3DES, 0 /* CBC */, data, key, iv));
-#else
- return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 1);
-#endif /* __APPLE__ */
}
vchar_t *
eay_3des_decrypt(data, key, iv)
vchar_t *data, *key, *iv;
{
-#ifdef __APPLE__
return(eay_CCCrypt(kCCDecrypt, kCCAlgorithm3DES, 0 /* CBC */, data, key, iv));
-#else
- return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 0);
-#endif /* __APPLE__ */
}
int
eay_3des_weakkey(key)
vchar_t *key;
-{
-#ifdef USE_NEW_DES_API
- return (DES_is_weak_key((void *)key->v) ||
- DES_is_weak_key((void *)(key->v + 8)) ||
- DES_is_weak_key((void *)(key->v + 16)));
-#else
- if (key->l < 24)
- return 0;
-
- return (des_is_weak_key((void *)key->v) ||
- des_is_weak_key((void *)(key->v + 8)) ||
- des_is_weak_key((void *)(key->v + 16)));
-#endif
-}
-
-int
-eay_3des_keylen(len)
- int len;
-{
-#ifdef __APPLE__
- /* CommonCrypto return lengths in bytes, ipsec-tools
- * uses lengths in bits, therefore conversion is required.
- */
- if (len != 0 && len != (kCCKeySize3DES << 3))
- return -1;
-
- return kCCKeySize3DES << 3;
-#else
- if (len != 0 && len != 192)
- return -1;
- return 192;
-#endif /* __APPLE__ */
-}
-
-/*
- * CAST-CBC
- */
-vchar_t *
-eay_cast_encrypt(data, key, iv)
- vchar_t *data, *key, *iv;
-{
- return evp_crypt(data, key, iv, EVP_cast5_cbc(), 1);
-}
-
-vchar_t *
-eay_cast_decrypt(data, key, iv)
- vchar_t *data, *key, *iv;
-{
- return evp_crypt(data, key, iv, EVP_cast5_cbc(), 0);
-}
-
-int
-eay_cast_weakkey(key)
- vchar_t *key;
-{
- return 0; /* No known weak keys. */
-}
-
-int
-eay_cast_keylen(len)
- int len;
-{
- if (len == 0)
- return 128;
- if (len < 40 || len > 128)
- return -1;
- return len;
-}
-
-/*
- * AES(RIJNDAEL)-CBC
- */
-#ifdef __APPLE__
-vchar_t *
-eay_aes_encrypt(data, key, iv)
-vchar_t *data, *key, *iv;
-{
- return(eay_CCCrypt(kCCEncrypt, kCCAlgorithmAES128 /* adapts to AES-192, or AES-256 depending on the key size*/, 0 /* CBC */, data, key, iv));
-}
-
-vchar_t *
-eay_aes_decrypt(data, key, iv)
-vchar_t *data, *key, *iv;
-{
- return(eay_CCCrypt(kCCDecrypt, kCCAlgorithmAES128 /* adapts to AES-192, or AES-256 depending on the key size*/, 0 /* CBC */, data, key, iv));
-}
-
-int
-eay_aes_keylen(len)
-int len;
-{
- /* CommonCrypto return lengths in bytes, ipsec-tools
- * uses lengths in bits, therefore conversion is required.
- */
- if (len != 0) {
- if (len != (kCCKeySizeAES128 << 3) &&
- len != (kCCKeySizeAES192 << 3) &&
- len != (kCCKeySizeAES256 << 3))
- return -1;
- } else {
- return kCCKeySizeAES128 << 3;
- }
- return len;
-}
-
-#else
-
-#ifndef HAVE_OPENSSL_AES_H
-vchar_t *
-eay_aes_encrypt(data, key, iv)
- vchar_t *data, *key, *iv;
-{
- vchar_t *res;
- keyInstance k;
- cipherInstance c;
-
- memset(&k, 0, sizeof(k));
- if (rijndael_makeKey(&k, DIR_ENCRYPT, key->l << 3, key->v) < 0)
- return NULL;
-
- /* allocate buffer for result */
- if ((res = vmalloc(data->l)) == NULL)
- return NULL;
-
- /* encryption data */
- memset(&c, 0, sizeof(c));
- if (rijndael_cipherInit(&c, MODE_CBC, iv->v) < 0){
- vfree(res);
- return NULL;
- }
- if (rijndael_blockEncrypt(&c, &k, data->v, data->l << 3, res->v) < 0){
- vfree(res);
- return NULL;
- }
-
- return res;
+{
+ return 0;
}
-vchar_t *
-eay_aes_decrypt(data, key, iv)
- vchar_t *data, *key, *iv;
+int
+eay_3des_keylen(len)
+ int len;
{
- vchar_t *res;
- keyInstance k;
- cipherInstance c;
-
- memset(&k, 0, sizeof(k));
- if (rijndael_makeKey(&k, DIR_DECRYPT, key->l << 3, key->v) < 0)
- return NULL;
-
- /* allocate buffer for result */
- if ((res = vmalloc(data->l)) == NULL)
- return NULL;
-
- /* decryption data */
- memset(&c, 0, sizeof(c));
- if (rijndael_cipherInit(&c, MODE_CBC, iv->v) < 0){
- vfree(res);
- return NULL;
- }
- if (rijndael_blockDecrypt(&c, &k, data->v, data->l << 3, res->v) < 0){
- vfree(res);
- return NULL;
- }
+ /* CommonCrypto return lengths in bytes, ipsec-tools
+ * uses lengths in bits, therefore conversion is required.
+ */
+ if (len != 0 && len != (kCCKeySize3DES << 3))
+ return -1;
- return res;
-}
-#else
-static inline const EVP_CIPHER *
-aes_evp_by_keylen(int keylen)
-{
- switch(keylen) {
- case 16:
- case 128:
- return EVP_aes_128_cbc();
- case 24:
- case 192:
- return EVP_aes_192_cbc();
- case 32:
- case 256:
- return EVP_aes_256_cbc();
- default:
- return NULL;
- }
+ return kCCKeySize3DES << 3;
}
+/*
+ * AES(RIJNDAEL)-CBC
+ */
vchar_t *
eay_aes_encrypt(data, key, iv)
- vchar_t *data, *key, *iv;
+vchar_t *data, *key, *iv;
{
- return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 1);
+ return(eay_CCCrypt(kCCEncrypt, kCCAlgorithmAES128 /* adapts to AES-192, or AES-256 depending on the key size*/, 0 /* CBC */, data, key, iv));
}
vchar_t *
eay_aes_decrypt(data, key, iv)
- vchar_t *data, *key, *iv;
+vchar_t *data, *key, *iv;
{
- return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 0);
+ return(eay_CCCrypt(kCCDecrypt, kCCAlgorithmAES128 /* adapts to AES-192, or AES-256 depending on the key size*/, 0 /* CBC */, data, key, iv));
}
-#endif /* HAVE_OPENSSL_AES_H */
int
eay_aes_keylen(len)
- int len;
+int len;
{
- if (len == 0)
- return 128;
- if (len != 128 && len != 192 && len != 256)
- return -1;
- return len;
+ /* CommonCrypto return lengths in bytes, ipsec-tools
+ * uses lengths in bits, therefore conversion is required.
+ */
+ if (len != 0) {
+ if (len != (kCCKeySizeAES128 << 3) &&
+ len != (kCCKeySizeAES192 << 3) &&
+ len != (kCCKeySizeAES256 << 3))
+ return -1;
+ } else {
+ return kCCKeySizeAES128 << 3;
+ }
+ return len;
}
-#endif /* __APPLE__ */
+
int
eay_aes_weakkey(key)
return 0;
}
-int
-eay_kpdk_hashlen()
-{
- return 0;
-}
-
-int
-eay_twofish_keylen(len)
- int len;
-{
- if (len < 0 || len > 256)
- return -1;
- return len;
-}
-
int
eay_null_keylen(len)
int len;
/*
* HMAC functions
*/
-
-#ifdef __APPLE__
static caddr_t
eay_hmac_init(key, algorithm)
vchar_t *key;
return (caddr_t)c;
}
-#else
-static caddr_t
-eay_hmac_init(key, md)
- vchar_t *key;
- const EVP_MD *md;
-{
- HMAC_CTX *c = racoon_malloc(sizeof(*c));
-
- HMAC_Init(c, key->v, key->l, md);
-
- return (caddr_t)c;
-}
-#endif /* __APPLE__ */
#ifdef WITH_SHA2
/*
eay_hmacsha2_512_init(key)
vchar_t *key;
{
-#ifdef __APPLE__
return eay_hmac_init(key, kCCHmacAlgSHA512);
-#else
- return eay_hmac_init(key, EVP_sha2_512());
-#endif
}
void
caddr_t c;
vchar_t *data;
{
-#ifdef __APPLE__
- CCHmacUpdate((CCHmacContext *)c, data->v, data->l);
-#else
- HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
-#endif
+ CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l);
}
-#ifdef __APPLE__
vchar_t *
eay_hmacsha2_512_final(c)
caddr_t c;
if ((res = vmalloc(CC_SHA512_DIGEST_LENGTH)) == 0)
return NULL;
- CCHmacFinal((CCHmacContext *)c, res->v);
+ CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v);
res->l = CC_SHA512_DIGEST_LENGTH;
(void)racoon_free(c);
return(res);
}
-#else
-vchar_t *
-eay_hmacsha2_512_final(c)
- caddr_t c;
-{
- vchar_t *res;
- unsigned int l;
-
- if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0)
- return NULL;
-
- HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
- res->l = l;
- HMAC_cleanup((HMAC_CTX *)c);
-
- (void)racoon_free(c);
-
- if (SHA512_DIGEST_LENGTH != res->l) {
- plog(LLV_ERROR, LOCATION, NULL,
- "hmac sha2_512 length mismatch %zd.\n", res->l);
- vfree(res);
- return NULL;
- }
-
- return(res);
-}
-#endif /* __APPLE__ */
/*
* HMAC SHA2-384
eay_hmacsha2_384_init(key)
vchar_t *key;
{
-#ifdef __APPLE__
return eay_hmac_init(key, kCCHmacAlgSHA384);
-#else
- return eay_hmac_init(key, EVP_sha2_384());
-#endif
}
void
caddr_t c;
vchar_t *data;
{
-#ifdef __APPLE__
- CCHmacUpdate((CCHmacContext *)c, data->v, data->l);
-#else
- HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
-#endif
+ CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l);
}
-#ifdef __APPLE__
vchar_t *
eay_hmacsha2_384_final(c)
caddr_t c;
if ((res = vmalloc(CC_SHA384_DIGEST_LENGTH)) == 0)
return NULL;
- CCHmacFinal((CCHmacContext *)c, res->v);
+ CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v);
res->l = CC_SHA384_DIGEST_LENGTH;
(void)racoon_free(c);
return(res);
}
-#else
-vchar_t *
-eay_hmacsha2_384_final(c)
- caddr_t c;
-{
- vchar_t *res;
- unsigned int l;
-
- if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0)
- return NULL;
-
- HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
- res->l = l;
- HMAC_cleanup((HMAC_CTX *)c);
-
- (void)racoon_free(c);
-
- if (SHA384_DIGEST_LENGTH != res->l) {
- plog(LLV_ERROR, LOCATION, NULL,
- "hmac sha2_384 length mismatch %zd.\n", res->l);
- vfree(res);
- return NULL;
- }
-
- return(res);
-}
-#endif /* __APPLE__ */
/*
* HMAC SHA2-256
eay_hmacsha2_256_init(key)
vchar_t *key;
{
-#ifdef __APPLE__
return eay_hmac_init(key, kCCHmacAlgSHA256);
-#else
- return eay_hmac_init(key, EVP_sha2_256());
-#endif
}
void
caddr_t c;
vchar_t *data;
{
-#ifdef __APPLE__
- CCHmacUpdate((CCHmacContext *)c, data->v, data->l);
-#else
- HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
-#endif
+ CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l);
}
-#ifdef __APPLE__
vchar_t *
eay_hmacsha2_256_final(c)
caddr_t c;
if ((res = vmalloc(CC_SHA256_DIGEST_LENGTH)) == 0)
return NULL;
- CCHmacFinal((CCHmacContext *)c, res->v);
+ CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v);
res->l = CC_SHA256_DIGEST_LENGTH;
(void)racoon_free(c);
return(res);
}
-#else
-vchar_t *
-eay_hmacsha2_256_final(c)
- caddr_t c;
-{
- vchar_t *res;
- unsigned int l;
-
- if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0)
- return NULL;
-
- HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
- res->l = l;
- HMAC_cleanup((HMAC_CTX *)c);
-
- (void)racoon_free(c);
-
- if (SHA256_DIGEST_LENGTH != res->l) {
- plog(LLV_ERROR, LOCATION, NULL,
- "hmac sha2_256 length mismatch %zd.\n", res->l);
- vfree(res);
- return NULL;
- }
-
- return(res);
-}
-#endif /* __APPLE__ */
#endif /* WITH_SHA2 */
/*
eay_hmacsha1_init(key)
vchar_t *key;
{
-#ifdef __APPLE__
return eay_hmac_init(key, kCCHmacAlgSHA1);
-#else
- return eay_hmac_init(key, EVP_sha1());
-#endif
}
void
caddr_t c;
vchar_t *data;
{
-#ifdef __APPLE__
- CCHmacUpdate((CCHmacContext *)c, data->v, data->l);
-#else
- HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
-#endif
+ CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l);
}
-#ifdef __APPLE__
vchar_t *
eay_hmacsha1_final(c)
caddr_t c;
if ((res = vmalloc(CC_SHA1_DIGEST_LENGTH)) == 0)
return NULL;
- CCHmacFinal((CCHmacContext *)c, res->v);
+ CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v);
res->l = CC_SHA1_DIGEST_LENGTH;
(void)racoon_free(c);
return(res);
}
-#else
-vchar_t *
-eay_hmacsha1_final(c)
- caddr_t c;
-{
- vchar_t *res;
- unsigned int l;
-
- if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0)
- return NULL;
-
- HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
- res->l = l;
- HMAC_cleanup((HMAC_CTX *)c);
-
- (void)racoon_free(c);
-
- if (SHA_DIGEST_LENGTH != res->l) {
- plog(LLV_ERROR, LOCATION, NULL,
- "hmac sha1 length mismatch %zd.\n", res->l);
- vfree(res);
- return NULL;
- }
-
- return(res);
-}
-#endif /* __APPLE__ */
/*
* HMAC MD5
eay_hmacmd5_init(key)
vchar_t *key;
{
-#ifdef __APPLE__
return eay_hmac_init(key, kCCHmacAlgMD5);
-#else
- return eay_hmac_init(key, EVP_md5());
-#endif
}
void
caddr_t c;
vchar_t *data;
{
-#ifdef __APPLE__
- CCHmacUpdate((CCHmacContext *)c, data->v, data->l);
-#else
- HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
-#endif
+ CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l);
}
-#ifdef __APPLE__
vchar_t *
eay_hmacmd5_final(c)
caddr_t c;
if ((res = vmalloc(CC_MD5_DIGEST_LENGTH)) == 0)
return NULL;
- CCHmacFinal((CCHmacContext *)c, res->v);
+ CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v);
res->l = CC_MD5_DIGEST_LENGTH;
(void)racoon_free(c);
return(res);
}
-#else
-vchar_t *
-eay_hmacmd5_final(c)
- caddr_t c;
-{
- vchar_t *res;
- unsigned int l;
-
- if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0)
- return NULL;
-
- HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
- res->l = l;
- HMAC_cleanup((HMAC_CTX *)c);
-
- (void)racoon_free(c);
- if (MD5_DIGEST_LENGTH != res->l) {
- plog(LLV_ERROR, LOCATION, NULL,
- "hmac md5 length mismatch %zd.\n", res->l);
- vfree(res);
- return NULL;
- }
- return(res);
-}
-#endif /* __APPLE__ */
#ifdef WITH_SHA2
/*
caddr_t c;
vchar_t *data;
{
- SHA512_Update((SHA512_CTX *)c, (unsigned char *) data->v, data->l);
+ SHA512_Update(ALIGNED_CAST(SHA512_CTX *)c, (unsigned char *) data->v, data->l);
return;
}
if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0)
return(0);
- SHA512_Final((unsigned char *) res->v, (SHA512_CTX *)c);
+ SHA512_Final((unsigned char *) res->v, ALIGNED_CAST(SHA512_CTX *)c);
(void)racoon_free(c);
return(res);
* SHA2-384 functions
*/
-#ifdef __APPLE__
typedef SHA512_CTX SHA384_CTX;
-#endif
caddr_t
eay_sha2_384_init()
caddr_t c;
vchar_t *data;
{
- SHA384_Update((SHA384_CTX *)c, (unsigned char *) data->v, data->l);
+ SHA384_Update(ALIGNED_CAST(SHA384_CTX *)c, (unsigned char *) data->v, data->l);
return;
}
if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0)
return(0);
- SHA384_Final((unsigned char *) res->v, (SHA384_CTX *)c);
+ SHA384_Final((unsigned char *) res->v, ALIGNED_CAST(SHA384_CTX *)c);
(void)racoon_free(c);
return(res);
caddr_t c;
vchar_t *data;
{
- SHA256_Update((SHA256_CTX *)c, (unsigned char *) data->v, data->l);
+ SHA256_Update(ALIGNED_CAST(SHA256_CTX *)c, (unsigned char *) data->v, data->l);
return;
}
if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0)
return(0);
- SHA256_Final((unsigned char *) res->v, (SHA256_CTX *)c);
+ SHA256_Final((unsigned char *) res->v, ALIGNED_CAST(SHA256_CTX *)c);
(void)racoon_free(c);
return(res);
caddr_t c;
vchar_t *data;
{
- SHA1_Update((SHA_CTX *)c, data->v, data->l);
+ SHA1_Update(ALIGNED_CAST(SHA_CTX *)c, data->v, data->l);
return;
}
if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0)
return(0);
- SHA1_Final((unsigned char *) res->v, (SHA_CTX *)c);
+ SHA1_Final((unsigned char *) res->v, ALIGNED_CAST(SHA_CTX *)c);
(void)racoon_free(c);
return(res);
caddr_t c;
vchar_t *data;
{
- MD5_Update((MD5_CTX *)c, data->v, data->l);
+ MD5_Update(ALIGNED_CAST(MD5_CTX *)c, data->v, data->l);
return;
}
if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0)
return(0);
- MD5_Final((unsigned char *) res->v, (MD5_CTX *)c);
+ MD5_Final((unsigned char *) res->v, ALIGNED_CAST(MD5_CTX *)c);
(void)racoon_free(c);
return(res);
return MD5_DIGEST_LENGTH << 3;
}
+
+#ifdef HAVE_OPENSSL
/*
* eay_set_random
* size: number of bytes.
BN_free(r);
return(res);
}
+#else
+vchar_t *
+eay_set_random(u_int32_t size)
+{
+ vchar_t *res = vmalloc(size);
+
+ if (res == NULL)
+ return NULL;
+
+ if (SecRandomCopyBytes(kSecRandomDefault, size, (uint8_t*)res->v)) {
+ vfree(res);
+ return NULL;
+ }
+
+ return res;
+}
+#endif
+#ifdef HAVE_OPENSSL
/* DH */
int
eay_dh_generate(prime, g, publen, pub, priv)
ENGINE_register_all_complete();
#endif
}
-
-vchar_t *
-base64_decode(char *in, long inlen)
-{
- BIO *bio=NULL, *b64=NULL;
- vchar_t *res = NULL;
- char *outb;
- long outlen;
-
- outb = malloc(inlen * 2);
- if (outb == NULL)
- goto out;
- bio = BIO_new_mem_buf(in, inlen);
- b64 = BIO_new(BIO_f_base64());
- BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
- bio = BIO_push(b64, bio);
-
- outlen = BIO_read(bio, outb, inlen * 2);
- if (outlen <= 0) {
- plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
- goto out;
- }
-
- res = vmalloc(outlen);
- if (!res)
- goto out;
-
- memcpy(res->v, outb, outlen);
-
-out:
- if (outb)
- free(outb);
- if (bio)
- BIO_free_all(bio);
-
- return res;
-}
-
-vchar_t *
-base64_encode(char *in, long inlen)
-{
- BIO *bio=NULL, *b64=NULL;
- char *ptr;
- long plen = -1;
- vchar_t *res = NULL;
-
- bio = BIO_new(BIO_s_mem());
- b64 = BIO_new(BIO_f_base64());
- BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
- bio = BIO_push(b64, bio);
-
- BIO_write(bio, in, inlen);
- BIO_flush(bio);
-
- plen = BIO_get_mem_data(bio, &ptr);
- res = vmalloc(plen+1);
- if (!res)
- goto out;
-
- memcpy (res->v, ptr, plen);
- res->v[plen] = '\0';
-
-out:
- if (bio)
- BIO_free_all(bio);
-
- return res;
-}
-
-static RSA *
-binbuf_pubkey2rsa(vchar_t *binbuf)
-{
- BIGNUM *exp, *mod;
- RSA *rsa_pub = NULL;
-
- if (binbuf->v[0] > binbuf->l - 1) {
- plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: decoded string doesn't make sense.\n");
- goto out;
- }
-
- exp = BN_bin2bn((unsigned char *) (binbuf->v + 1), binbuf->v[0], NULL);
- mod = BN_bin2bn((unsigned char *) (binbuf->v + binbuf->v[0] + 1),
- binbuf->l - binbuf->v[0] - 1, NULL);
- rsa_pub = RSA_new();
-
- if (!exp || !mod || !rsa_pub) {
- plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey parsing error: %s\n", eay_strerror());
- if (exp)
- BN_free(exp);
- if (mod)
- BN_free(exp);
- if (rsa_pub)
- RSA_free(rsa_pub);
- rsa_pub = NULL;
- goto out;
- }
-
- rsa_pub->n = mod;
- rsa_pub->e = exp;
-
-out:
- return rsa_pub;
-}
-
-RSA *
-base64_pubkey2rsa(char *in)
-{
- BIGNUM *exp, *mod;
- RSA *rsa_pub = NULL;
- vchar_t *binbuf;
-
- if (strncmp(in, "0s", 2) != 0) {
- plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: doesn't start with '0s'\n");
- return NULL;
- }
-
- binbuf = base64_decode(in + 2, strlen(in + 2));
- if (!binbuf) {
- plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: Base64 decoding failed.\n");
- return NULL;
- }
-
- if (binbuf->v[0] > binbuf->l - 1) {
- plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: decoded string doesn't make sense.\n");
- goto out;
- }
-
- rsa_pub = binbuf_pubkey2rsa(binbuf);
-
-out:
- if (binbuf)
- vfree(binbuf);
-
- return rsa_pub;
-}
-
-RSA *
-bignum_pubkey2rsa(BIGNUM *in)
-{
- RSA *rsa_pub = NULL;
- vchar_t *binbuf;
-
- binbuf = vmalloc(BN_num_bytes(in));
- if (!binbuf) {
- plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey conversion: memory allocation failed..\n");
- return NULL;
- }
-
- BN_bn2bin(in, (unsigned char *) binbuf->v);
-
- rsa_pub = binbuf_pubkey2rsa(binbuf);
-
-out:
- if (binbuf)
- vfree(binbuf);
-
- return rsa_pub;
-}
+#endif /* HAVE_OPENSSL */
u_int32_t
eay_random()
return result;
}
+#ifdef HAVE_OPENSSL
const char *
eay_version()
{
return SSLeay_version(SSLEAY_VERSION);
}
+#endif