1c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/*	$NetBSD: crypto_openssl.c,v 1.11.6.6 2009/04/29 10:50:25 tteras Exp $	*/
20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Id: crypto_openssl.c,v 1.47 2006/05/06 20:42:09 manubsd Exp */
40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * All rights reserved.
80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without
100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions
110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met:
120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright
130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer.
140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright
150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer in the
160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    documentation and/or other materials provided with the distribution.
170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors
180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    may be used to endorse or promote products derived from this software
190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    without specific prior written permission.
200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE.
320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h"
350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/types.h>
370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/param.h>
380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdlib.h>
400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdio.h>
410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <limits.h>
420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <string.h>
430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* get openssl/ssleay version number */
450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/opensslv.h>
460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090602fL)
480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#error OpenSSL version 0.9.6 or later required.
490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/pem.h>
520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/evp.h>
530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/x509.h>
540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/x509v3.h>
550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/x509_vfy.h>
560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/bn.h>
570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/dh.h>
580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/md5.h>
590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/sha.h>
600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/hmac.h>
610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/des.h>
620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/crypto.h>
630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_ENGINE_H
640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/engine.h>
650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
66458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh#ifndef ANDROID_CHANGES
670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/blowfish.h>
680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/cast.h>
69458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh#else
70458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh#define EVP_bf_cbc()    NULL
71458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh#define EVP_cast5_cbc() NULL
72458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh#endif
730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/err.h>
740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_RC5_H
750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/rc5.h>
760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_IDEA_H
780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/idea.h>
790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if defined(HAVE_OPENSSL_AES_H)
810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/aes.h>
820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#elif defined(HAVE_OPENSSL_RIJNDAEL_H)
830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/rijndael.h>
840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "crypto/rijndael/rijndael-api-fst.h"
860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if defined(HAVE_OPENSSL_CAMELLIA_H)
880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/camellia.h>
890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef WITH_SHA2
910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_SHA2_H
920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/sha2.h>
930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "crypto/sha2/sha2.h"
950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h"
980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 0.9.7 stuff? */
1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if OPENSSL_VERSION_NUMBER < 0x0090700fL
1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangtypedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define USE_NEW_DES_API
1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define OpenSSL_BUG()	do { plog(LLV_ERROR, LOCATION, NULL, "OpenSSL function failed\n"); } while(0)
1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "var.h"
1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h"
1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h"
1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h"
1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "crypto_openssl.h"
1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "debug.h"
1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "gcmalloc.h"
1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * I hate to cast every parameter to des_xx into void *, but it is
1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * necessary for SSLeay/OpenSSL portability.  It sucks.
1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int cb_check_cert_local __P((int, X509_STORE_CTX *));
1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int cb_check_cert_remote __P((int, X509_STORE_CTX *));
1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic X509 *mem2x509 __P((vchar_t *));
1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic caddr_t eay_hmac_init __P((vchar_t *, const EVP_MD *));
1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* X509 Certificate */
1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * convert the string of the subject name into DER
1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * e.g. str = "C=JP, ST=Kanagawa";
1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_str2asn1dn(str, len)
1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const char *str;
1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_NAME *name;
138c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	char *buf;
1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *field, *value;
140c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int i, j;
1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *ret = NULL;
1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t p;
1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == -1)
1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = strlen(str);
1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf = racoon_malloc(len + 1);
1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!buf) {
1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n");
1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(buf, str, len);
1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	name = X509_NAME_new();
1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
156c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	field = &buf[0];
1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	value = NULL;
1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < len; i++) {
1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!value && buf[i] == '=') {
160c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			buf[i] = '\0';
161c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			value = &buf[i + 1];
1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else if (buf[i] == ',' || buf[i] == '/') {
164c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			buf[i] = '\0';
1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n",
1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     field, value);
1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!value) goto err;
1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!X509_NAME_add_entry_by_txt(name, field,
1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					(value[0] == '*' && value[1] == 0) ?
1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						V_ASN1_PRINTABLESTRING : MBSTRING_ASC,
1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					(unsigned char *) value, -1, -1, 0)) {
1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     "Invalid DN field: %s=%s\n",
1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     field, value);
1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     "%s\n", eay_strerror());
1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err;
1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
181c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			for (j = i + 1; j < len; j++) {
182c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				if (buf[j] != ' ')
183c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					break;
184c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
185c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			field = &buf[j];
1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			value = NULL;
1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
1890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
190c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	buf[len] = '\0';
1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n",
1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	     field, value);
1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!value) goto err;
1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!X509_NAME_add_entry_by_txt(name, field,
1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(value[0] == '*' && value[1] == 0) ?
1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				V_ASN1_PRINTABLESTRING : MBSTRING_ASC,
1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(unsigned char *) value, -1, -1, 0)) {
2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     "Invalid DN field: %s=%s\n",
2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     field, value);
2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     "%s\n", eay_strerror());
2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	i = i2d_X509_NAME(name, NULL);
2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!i)
2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = vmalloc(i);
2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!ret)
2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = ret->v;
2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	i = i2d_X509_NAME(name, (void *)&p);
2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!i)
2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ret;
2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    err:
2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf)
2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(buf);
2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (name)
2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_NAME_free(name);
2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ret)
2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(ret);
2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * convert the hex string of the subject name into DER
2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hex2asn1dn(const char *hex, int len)
2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *bn = BN_new();
2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *binbuf;
2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t binlen;
2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *ret = NULL;
2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == -1)
2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = strlen(hex);
2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (BN_hex2bn(&bn, hex) != len) {
2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     "conversion of Hex-encoded ASN1 string to binary failed: %s\n",
2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     eay_strerror());
2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	binlen = BN_num_bytes(bn);
2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = vmalloc(binlen);
2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!ret) {
2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n");
2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	binbuf = ret->v;
2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BN_bn2bin(bn, (unsigned char *) binbuf);
2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BN_free(bn);
2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ret;
2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * The following are derived from code in crypto/x509/x509_cmp.c
2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * in OpenSSL0.9.7c:
2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * X509_NAME_wildcmp() adds wildcard matching to the original
2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * X509_NAME_cmp(), nocase_cmp() and nocase_spacenorm_cmp() are as is.
2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <ctype.h>
2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Case insensitive string comparision */
2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (a->length != b->length)
2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return (a->length - b->length);
2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i=0; i<a->length; i++)
2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int ca, cb;
2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ca = tolower(a->data[i]);
2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		cb = tolower(b->data[i]);
2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ca != cb)
2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return(ca-cb);
2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Case insensitive string comparision with space normalization
2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Space normalization - ignore leading, trailing spaces,
2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *       multiple spaces between characters are replaced by single space
2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned char *pa = NULL, *pb = NULL;
3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int la, lb;
3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	la = a->length;
3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lb = b->length;
3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pa = a->data;
3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pb = b->data;
3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* skip leading spaces */
3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (la > 0 && isspace(*pa))
3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		la--;
3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pa++;
3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (lb > 0 && isspace(*pb))
3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		lb--;
3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pb++;
3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* skip trailing spaces */
3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (la > 0 && isspace(pa[la-1]))
3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		la--;
3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (lb > 0 && isspace(pb[lb-1]))
3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		lb--;
3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* compare strings with space normalization */
3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (la > 0 && lb > 0)
3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int ca, cb;
3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* compare character */
3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ca = tolower(*pa);
3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		cb = tolower(*pb);
3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ca != cb)
3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return (ca - cb);
3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pa++; pb++;
3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		la--; lb--;
3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (la <= 0 || lb <= 0)
3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* is white space next character ? */
3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isspace(*pa) && isspace(*pb))
3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* skip remaining white spaces */
3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			while (la > 0 && isspace(*pa))
3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			{
3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				la--;
3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pa++;
3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			while (lb > 0 && isspace(*pb))
3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			{
3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				lb--;
3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pb++;
3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (la > 0 || lb > 0)
3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return la - lb;
3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int X509_NAME_wildcmp(const X509_NAME *a, const X509_NAME *b)
3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
3690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    int i,j;
3700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    X509_NAME_ENTRY *na,*nb;
3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    if (sk_X509_NAME_ENTRY_num(a->entries)
3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	!= sk_X509_NAME_ENTRY_num(b->entries))
3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    return sk_X509_NAME_ENTRY_num(a->entries)
3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	      -sk_X509_NAME_ENTRY_num(b->entries);
3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    na=sk_X509_NAME_ENTRY_value(a->entries,i);
3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    nb=sk_X509_NAME_ENTRY_value(b->entries,i);
3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    j=OBJ_cmp(na->object,nb->object);
3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    if (j) return(j);
3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    if ((na->value->length == 1 && na->value->data[0] == '*')
3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	     || (nb->value->length == 1 && nb->value->data[0] == '*'))
3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    continue;
3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    j=na->value->type-nb->value->type;
3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    if (j) return(j);
3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    if (na->value->type == V_ASN1_PRINTABLESTRING)
3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    j=nocase_spacenorm_cmp(na->value, nb->value);
3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    else if (na->value->type == V_ASN1_IA5STRING
3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    j=nocase_cmp(na->value, nb->value);
3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    else
3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    {
3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    j=na->value->length-nb->value->length;
3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    if (j) return(j);
3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    j=memcmp(na->value->data,nb->value->data,
3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    na->value->length);
3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    }
3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    if (j) return(j);
4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    j=na->set-nb->set;
4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    if (j) return(j);
4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    return(0);
4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * compare two subjectNames.
4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT:        0: equal
4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	positive:
4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	      -1: other error.
4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_cmp_asn1dn(n1, n2)
4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *n1, *n2;
4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_NAME *a = NULL, *b = NULL;
4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t p;
4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i = -1;
4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = n1->v;
4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!d2i_X509_NAME(&a, (void *)&p, n1->l))
4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = n2->v;
4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!d2i_X509_NAME(&b, (void *)&p, n2->l))
4260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
4270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	i = X509_NAME_wildcmp(a, b);
4290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    end:
4310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (a)
4320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_NAME_free(a);
4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (b)
4340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_NAME_free(b);
4350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return i;
4360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
4370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
438b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh#ifdef ANDROID_CHANGES
439e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh
440e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yehstatic BIO *BIO_from_android(char *path)
441c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{
442e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	void *data;
4438f3b38855d8849959825acc45dd11144adc7d862Chia-chi Yeh	if (sscanf(path, pname, &data) == 1) {
444e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		return BIO_new_mem_buf(data, -1);
445b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh	}
446e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	return NULL;
447b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh}
448b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh
449e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#endif
450b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh
4510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this functions is derived from apps/verify.c in OpenSSL0.9.5
4530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
4540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
4550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_check_x509cert(cert, CApath, CAfile, local)
4560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
4570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *CApath;
4580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *CAfile;
4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int local;
4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE *cert_ctx = NULL;
4620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_LOOKUP *lookup = NULL;
4630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509 = NULL;
4640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE_CTX *csc;
4650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
4660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	cert_ctx = X509_STORE_new();
4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (cert_ctx == NULL)
4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
4700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (local)
4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_local);
4730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
4740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_remote);
4750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
476e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#ifdef ANDROID_CHANGES
4778f3b38855d8849959825acc45dd11144adc7d862Chia-chi Yeh	if (pname) {
478fd76ec530c3f9cd0b9cc03501d02b6cb3ba705edChia-chi Yeh		BIO *bio = BIO_from_android(CAfile);
4795cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		STACK_OF(X509_INFO) *stack;
4805cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		X509_INFO *info;
4815cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		int i;
4825cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh
4835cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		if (!bio) {
4845cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			goto end;
4855cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		}
4865cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
4875cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		BIO_free(bio);
4885cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		if (!stack) {
4895cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			goto end;
4905cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		}
4915cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		for (i = 0; i < sk_X509_INFO_num(stack); ++i) {
4925cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			info = sk_X509_INFO_value(stack, i);
4935cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			if (info->x509) {
4945cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh				X509_STORE_add_cert(cert_ctx, info->x509);
4955cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			}
4965cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			if (info->crl) {
4975cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh				X509_STORE_add_crl(cert_ctx, info->crl);
4985cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			}
499b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh		}
5005cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		sk_X509_INFO_pop_free(stack, X509_INFO_free);
501e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	} else {
502e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#endif
503e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
504e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	if (lookup == NULL)
505e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		goto end;
506e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh
507e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	X509_LOOKUP_load_file(lookup, CAfile,
508e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	    (CAfile == NULL) ? X509_FILETYPE_DEFAULT : X509_FILETYPE_PEM);
509e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh
510e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
511e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	if (lookup == NULL)
512e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		goto end;
513e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	error = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM);
514e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	if(!error) {
515e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		error = -1;
516e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		goto end;
517e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	}
518e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	error = -1;	/* initialized */
519e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#ifdef ANDROID_CHANGES
520b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh	}
521b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh#endif
5220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* read the certificate to be verified */
5240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = mem2x509(cert);
5250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 == NULL)
5260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
5270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	csc = X509_STORE_CTX_new();
5290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (csc == NULL)
5300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
5310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE_CTX_init(csc, cert_ctx, x509, NULL);
5320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK);
5340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK_ALL);
5350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = X509_verify_cert(csc);
537051f86dfca525c160855397f7b6a4fb5ef8df2b5Chia-chi Yeh	X509_STORE_CTX_free(csc);
5380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
5400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * if x509_verify_cert() is successful then the value of error is
5410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * set non-zero.
5420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = error ? 0 : -1;
5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error)
5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,"%s\n", eay_strerror());
5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (cert_ctx != NULL)
5490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_STORE_free(cert_ctx);
5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 != NULL)
5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_free(x509);
5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(error);
5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * callback function for verifing certificate.
5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function is derived from cb() in openssl/apps/s_server.c
5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcb_check_cert_local(ok, ctx)
5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ok;
5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE_CTX *ctx;
5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char buf[256];
5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int log_tag;
5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!ok) {
5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_NAME_oneline(
5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				X509_get_subject_name(ctx->current_cert),
5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				buf,
5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				256);
5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * since we are just checking the certificates, it is
5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * ok if they are self signed. But we should still warn
5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * the user.
5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 		 */
5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (ctx->error) {
5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_CERT_HAS_EXPIRED:
5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_INVALID_CA:
5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_PATH_LENGTH_EXCEEDED:
5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_INVALID_PURPOSE:
5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_UNABLE_TO_GET_CRL:
5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ok = 1;
5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			log_tag = LLV_WARNING;
5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			log_tag = LLV_ERROR;
5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(log_tag, LOCATION, NULL,
5920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s(%d) at depth:%d SubjectName:%s\n",
5930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_verify_cert_error_string(ctx->error),
5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ctx->error,
5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ctx->error_depth,
5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			buf);
5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ERR_clear_error();
5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ok;
6010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * callback function for verifing remote certificates.
6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function is derived from cb() in openssl/apps/s_server.c
6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcb_check_cert_remote(ok, ctx)
6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ok;
6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE_CTX *ctx;
6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char buf[256];
6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int log_tag;
6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!ok) {
6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_NAME_oneline(
6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				X509_get_subject_name(ctx->current_cert),
6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				buf,
6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				256);
6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (ctx->error) {
6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_UNABLE_TO_GET_CRL:
6220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ok = 1;
6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			log_tag = LLV_WARNING;
6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			log_tag = LLV_ERROR;
6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(log_tag, LOCATION, NULL,
6290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s(%d) at depth:%d SubjectName:%s\n",
6300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_verify_cert_error_string(ctx->error),
6310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ctx->error,
6320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ctx->error_depth,
6330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			buf);
6340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ERR_clear_error();
6360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ok;
6380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
641c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * get a subjectAltName from X509 certificate.
6420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
6430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_x509asn1subjectname(cert)
6450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
6460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509 = NULL;
6480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp;
6490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *name = NULL;
6500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
6510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
652c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	bp = (unsigned char *) cert->v;
653c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = mem2x509(cert);
6550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 == NULL)
6560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto error;
6570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get the length of the name */
6590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = i2d_X509_NAME(x509->cert_info->subject, NULL);
6600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	name = vmalloc(len);
6610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!name)
6620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto error;
6630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get the name */
6640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = (unsigned char *) name->v;
6650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = i2d_X509_NAME(x509->cert_info->subject, &bp);
6660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_free(x509);
6680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return name;
6700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerror:
6720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
6730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (name != NULL)
6750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(name);
6760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 != NULL)
6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_free(x509);
6790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
6810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
6840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get the subjectAltName from X509 certificate.
6850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * the name must be terminated by '\0'.
6860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
6880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_x509subjectaltname(cert, altname, type, pos)
6890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
6900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char **altname;
6910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *type;
6920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pos;
6930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509 = NULL;
6950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	GENERAL_NAMES *gens = NULL;
6960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	GENERAL_NAME *gen;
6970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
6980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
6990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*altname = NULL;
7010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*type = GENT_OTHERNAME;
7020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = mem2x509(cert);
7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 == NULL)
7050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
7060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gens = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
7080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (gens == NULL)
7090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
7100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* there is no data at "pos" */
7120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pos > sk_GENERAL_NAME_num(gens))
7130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
7140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gen = sk_GENERAL_NAME_value(gens, pos - 1);
7160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* read DNSName / Email */
7180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (gen->type == GEN_DNS	||
7190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		gen->type == GEN_EMAIL	||
7200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		gen->type == GEN_URI )
7210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
7220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* make sure if the data is terminated by '\0'. */
7230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (gen->d.ia5->data[gen->d.ia5->length] != '\0')
7240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
7250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
7260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "data is not terminated by NUL.");
7270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_hexdump(gen->d.ia5->data, gen->d.ia5->length + 1);
7280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
7290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = gen->d.ia5->length + 1;
7320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*altname = racoon_malloc(len);
7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!*altname)
7340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
7350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		strlcpy(*altname, (char *) gen->d.ia5->data, len);
7370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*type = gen->type;
7380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		error = 0;
7390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* read IP address */
7410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else if (gen->type == GEN_IPADD)
7420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
7430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		unsigned char p[5], *ip;
7440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ip = p;
7450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* only support IPv4 */
7470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (gen->d.ip->length != 4)
7480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
7490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* convert Octet String to String
7510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * XXX ???????
7520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
7530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*i2d_ASN1_OCTET_STRING(gen->d.ip,&ip);*/
7540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ip = gen->d.ip->data;
7550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX Magic, enough for an IPv4 address
7570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
7580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*altname = racoon_malloc(20);
7590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!*altname)
7600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
7610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sprintf(*altname, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
7630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*type = gen->type;
7640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		error = 0;
7650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX other possible types ?
7670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * For now, error will be -1 if unsupported type
7680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
7690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
7710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error) {
7720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*altname) {
7730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(*altname);
7740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*altname = NULL;
7750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
7770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509)
7790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_free(x509);
7800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (gens)
7810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* free the whole stack. */
7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
7830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
7850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * decode a X509 certificate and make a readable text terminated '\n'.
7900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * return the buffer allocated, so must free it later.
7910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
7920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *
7930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_x509text(cert)
7940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
7950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509 = NULL;
7970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO *bio = NULL;
7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *text = NULL;
7990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp = NULL;
8000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0;
8010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
8020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = mem2x509(cert);
8040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 == NULL)
8050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bio = BIO_new(BIO_s_mem());
8080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bio == NULL)
8090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = X509_print(bio, x509);
8120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 1) {
8130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		error = -1;
8140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = BIO_get_mem_data(bio, &bp);
8180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	text = racoon_malloc(len + 1);
8190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (text == NULL)
8200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(text, bp, len);
8220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	text[len] = '\0';
8230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
8250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    end:
8270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error) {
8280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (text) {
8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(text);
8300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			text = NULL;
8310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bio)
8350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		BIO_free(bio);
8360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509)
8370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_free(x509);
8380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return text;
8400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* get X509 structure from buffer. */
8430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic X509 *
8440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangmem2x509(cert)
8450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
8460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509;
8480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef EAYDEBUG
8500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp;
8520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
853c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	bp = (unsigned char *) cert->v;
8540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
855c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	x509 = d2i_X509(NULL, (void *)&bp, cert->l);
8560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
8570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
8580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO *bio;
8600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
8610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bio = BIO_new(BIO_s_mem());
8630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bio == NULL)
8640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
865c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	len = BIO_write(bio, cert->v, cert->l);
8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == -1)
8670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
8680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO_free(bio);
8700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
8710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return x509;
8730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
8760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get a X509 certificate from local file.
8770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * a certificate must be PEM format.
8780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Input:
8790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	path to a certificate.
8800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Output:
8810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	NULL if error occured
8820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	other is the cert.
8830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
8840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
8850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_x509cert(path)
8860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *path;
8870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	FILE *fp;
8890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509;
8900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
8910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp;
8920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
8930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
8940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
895b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh#ifdef ANDROID_CHANGES
8968f3b38855d8849959825acc45dd11144adc7d862Chia-chi Yeh	if (pname) {
897e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		BIO *bio = BIO_from_android(path);
898e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		if (!bio) {
899e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh			return NULL;
900e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		}
901b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh		x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
902b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh		BIO_free(bio);
903e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	} else {
904e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#endif
9050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Read private key */
9060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fp = fopen(path, "r");
9070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (fp == NULL)
9080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
9090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = PEM_read_X509(fp, NULL, NULL, NULL);
9100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fclose (fp);
911e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#ifdef ANDROID_CHANGES
912e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	}
913b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh#endif
9140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 == NULL)
9160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
9170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = i2d_X509(x509, NULL);
919c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	cert = vmalloc(len);
9200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (cert == NULL) {
9210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_free(x509);
9220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
9230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
924c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	bp = (unsigned char *) cert->v;
9250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = i2d_X509(x509, &bp);
9260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_free(x509);
9270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error == 0) {
9290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(cert);
9300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
9310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return cert;
9340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
9370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check a X509 signature
9380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	XXX: to be get hash type from my cert ?
9390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *		to be handled EVP_dss().
9400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT: return -1 when error.
9410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0
9420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
9430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
9440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_check_x509sign(source, sig, cert)
9450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *source;
9460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sig;
9470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
9480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509;
950c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	u_char *bp;
9510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_PKEY *evp;
9520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int res;
9530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
954c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	bp = (unsigned char *) cert->v;
955c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
956c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	x509 = d2i_X509(NULL, (void *)&bp, cert->l);
957c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (x509 == NULL) {
958c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_ERROR, LOCATION, NULL, "d2i_X509(): %s\n", eay_strerror());
9590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
960c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
9610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	evp = X509_get_pubkey(x509);
9630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (! evp) {
9640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "X509_get_pubkey(): %s\n", eay_strerror());
9651c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		X509_free(x509);
9660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = eay_rsa_verify(source, sig, evp->pkey.rsa);
9700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_PKEY_free(evp);
9721c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	X509_free(x509);
9730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
9750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
9780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check RSA signature
9790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT: return -1 when error.
9800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0 on success
9810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
9820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
9830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_check_rsasign(source, sig, rsa)
9840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *source;
9850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sig;
9860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RSA *rsa;
9870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_rsa_verify(source, sig, rsa);
9890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
9920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get PKCS#1 Private Key of PEM format from local file.
9930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
9940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
9950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_pkcs1privkey(path)
9960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *path;
9970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	FILE *fp;
9990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_PKEY *evp = NULL;
10000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *pkey = NULL;
10010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp;
10020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pkeylen;
10030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
10040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1005b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh#ifdef ANDROID_CHANGES
10068f3b38855d8849959825acc45dd11144adc7d862Chia-chi Yeh	if (pname) {
1007e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		BIO *bio = BIO_from_android(path);
1008e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		if (!bio) {
1009e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh			return NULL;
1010e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		}
1011b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh		evp = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
1012b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh		BIO_free(bio);
1013e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	} else {
1014e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#endif
10150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Read private key */
10160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fp = fopen(path, "r");
10170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (fp == NULL)
10180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
10190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	evp = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
10210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fclose (fp);
1023e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#ifdef ANDROID_CHANGES
1024e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	}
1025b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh#endif
10260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (evp == NULL)
10280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
10290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pkeylen = i2d_PrivateKey(evp, NULL);
10310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkeylen == 0)
10320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
10330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pkey = vmalloc(pkeylen);
10340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkey == NULL)
10350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
10360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = (unsigned char *) pkey->v;
10370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pkeylen = i2d_PrivateKey(evp, &bp);
10380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkeylen == 0)
10390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
10400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
10420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
10440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (evp != NULL)
10450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		EVP_PKEY_free(evp);
10460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0 && pkey != NULL) {
10470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(pkey);
10480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pkey = NULL;
10490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return pkey;
10520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
10550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get PKCS#1 Public Key of PEM format from local file.
10560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
10570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
10580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_pkcs1pubkey(path)
10590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *path;
10600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	FILE *fp;
10620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_PKEY *evp = NULL;
10630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *pkey = NULL;
10640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509 = NULL;
10650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp;
10660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pkeylen;
10670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
10680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Read private key */
10700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fp = fopen(path, "r");
10710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (fp == NULL)
10720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
10730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = PEM_read_X509(fp, NULL, NULL, NULL);
10750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fclose (fp);
10770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 == NULL)
10790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
10800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Get public key - eay */
10820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	evp = X509_get_pubkey(x509);
10830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (evp == NULL)
10840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
10850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pkeylen = i2d_PublicKey(evp, NULL);
10870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkeylen == 0)
10880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
10890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pkey = vmalloc(pkeylen);
10900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkey == NULL)
10910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
10920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = (unsigned char *) pkey->v;
10930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pkeylen = i2d_PublicKey(evp, &bp);
10940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkeylen == 0)
10950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
10960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
10980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
10990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (evp != NULL)
11000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		EVP_PKEY_free(evp);
11010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0 && pkey != NULL) {
11020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(pkey);
11030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pkey = NULL;
11040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return pkey;
11070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
11100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_x509sign(src, privkey)
11110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *src, *privkey;
11120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_PKEY *evp;
11140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp = (unsigned char *) privkey->v;
11150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sig = NULL;
11160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
11170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pad = RSA_PKCS1_PADDING;
11180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX to be handled EVP_PKEY_DSA */
11200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	evp = d2i_PrivateKey(EVP_PKEY_RSA, NULL, (void *)&bp, privkey->l);
11210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (evp == NULL)
11220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
11230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sig = eay_rsa_sign(src, evp->pkey.rsa);
11250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_PKEY_free(evp);
11270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return sig;
11290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
11320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_rsasign(src, rsa)
11330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *src;
11340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RSA *rsa;
11350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_rsa_sign(src, rsa);
11370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
11400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_rsa_sign(vchar_t *src, RSA *rsa)
11410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
11430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sig = NULL;
11440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pad = RSA_PKCS1_PADDING;
11450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = RSA_size(rsa);
11470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sig = vmalloc(len);
11490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sig == NULL)
11500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
11510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = RSA_private_encrypt(src->l, (unsigned char *) src->v,
11530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(unsigned char *) sig->v, rsa, pad);
11540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0 || len != sig->l) {
11560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(sig);
11570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sig = NULL;
11580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return sig;
11610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
11640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_rsa_verify(src, sig, rsa)
11650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *src, *sig;
11660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RSA *rsa;
11670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *xbuf = NULL;
11690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pad = RSA_PKCS1_PADDING;
11700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0;
11710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
11720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = RSA_size(rsa);
11740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xbuf = vmalloc(len);
11750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xbuf == NULL) {
11760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
11770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = RSA_public_decrypt(sig->l, (unsigned char *) sig->v,
11810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(unsigned char *) xbuf->v, rsa, pad);
11820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0 || len != src->l) {
11830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
11840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(xbuf);
11850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = memcmp(src->v, xbuf->v, src->l);
11890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(xbuf);
11900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0)
11910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
11940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
11970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get error string
11980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * MUST load ERR_load_crypto_strings() first.
11990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
12000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *
12010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_strerror()
12020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	static char ebuf[512];
12040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0, n;
12050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned long l;
12060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char buf[200];
12070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const char *file, *data;
12080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int line, flags;
12090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned long es;
12100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	es = CRYPTO_thread_id();
12120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0){
12140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		n = snprintf(ebuf + len, sizeof(ebuf) - len,
12150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"%lu:%s:%s:%d:%s ",
12160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				es, ERR_error_string(l, buf), file, line,
12170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(flags & ERR_TXT_STRING) ? data : "");
12180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (n < 0 || n >= sizeof(ebuf) - len)
12190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
12200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len += n;
12210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sizeof(ebuf) < len)
12220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
12230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ebuf;
12260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
12290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangevp_crypt(vchar_t *data, vchar_t *key, vchar_t *iv, const EVP_CIPHER *e, int enc)
12300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
12320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_CIPHER_CTX ctx;
12330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!e)
12350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
12360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (data->l % EVP_CIPHER_block_size(e))
12380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
12390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
12410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
12420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_CIPHER_CTX_init(&ctx);
12440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch(EVP_CIPHER_nid(e)){
12460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_bf_cbc:
12470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_bf_ecb:
12480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_bf_cfb64:
12490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_bf_ofb64:
12500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_cast5_cbc:
12510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_cast5_ecb:
12520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_cast5_cfb64:
12530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_cast5_ofb64:
12540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX: can we do that also for algos with a fixed key size ?
12550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
12560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* init context without key/iv
12570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang         */
12580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        if (!EVP_CipherInit(&ctx, e, NULL, NULL, enc))
12590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        {
12600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            OpenSSL_BUG();
12610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            vfree(res);
12620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            return NULL;
12630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        }
12640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        /* update key size
12660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang         */
12670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        if (!EVP_CIPHER_CTX_set_key_length(&ctx, key->l))
12680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        {
12690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            OpenSSL_BUG();
12700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            vfree(res);
12710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            return NULL;
12720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        }
12730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        /* finalize context init with desired key size
12750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang         */
12760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        if (!EVP_CipherInit(&ctx, NULL, (u_char *) key->v,
12770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							(u_char *) iv->v, enc))
12780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        {
12790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            OpenSSL_BUG();
12800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            vfree(res);
12810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            return NULL;
12820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
12840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
12850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!EVP_CipherInit(&ctx, e, (u_char *) key->v,
12860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							(u_char *) iv->v, enc)) {
12870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			OpenSSL_BUG();
12880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(res);
12890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
12900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* disable openssl padding */
12940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_CIPHER_CTX_set_padding(&ctx, 0);
12950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!EVP_Cipher(&ctx, (u_char *) res->v, (u_char *) data->v, data->l)) {
12970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		OpenSSL_BUG();
12980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
12990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
13000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_CIPHER_CTX_cleanup(&ctx);
13030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
13050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
13080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangevp_weakkey(vchar_t *key, const EVP_CIPHER *e)
13090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
13110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
13140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangevp_keylen(int len, const EVP_CIPHER *e)
13150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!e)
13170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* EVP functions return lengths in bytes, ipsec-tools
13190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * uses lengths in bits, therefore conversion is required. --AK
13200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
13210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != 0 && len != (EVP_CIPHER_key_length(e) << 3))
13220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return EVP_CIPHER_key_length(e) << 3;
13250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
13280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DES-CBC
13290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
13300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
13310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_des_encrypt(data, key, iv)
13320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
13330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_des_cbc(), 1);
13350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
13380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_des_decrypt(data, key, iv)
13390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
13400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_des_cbc(), 0);
13420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
13450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_des_weakkey(key)
13460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
13470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef USE_NEW_DES_API
13490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return DES_is_weak_key((void *)key->v);
13500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
13510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return des_is_weak_key((void *)key->v);
13520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
13560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_des_keylen(len)
13570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
13580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_keylen(len, EVP_des_cbc());
13600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_IDEA_H
13630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
13640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IDEA-CBC
13650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
13660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
13670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_idea_encrypt(data, key, iv)
13680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
13690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
13710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	IDEA_KEY_SCHEDULE ks;
13720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	idea_set_encrypt_key((unsigned char *)key->v, &ks);
13740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for result */
13760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
13770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
13780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* decryption data */
13800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	idea_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
13810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&ks, (unsigned char *)iv->v, IDEA_ENCRYPT);
13820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
13840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
13870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_idea_decrypt(data, key, iv)
13880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
13890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
13910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	IDEA_KEY_SCHEDULE ks, dks;
13920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	idea_set_encrypt_key((unsigned char *)key->v, &ks);
13940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	idea_set_decrypt_key(&ks, &dks);
13950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for result */
13970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
13980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
13990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* decryption data */
14010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	idea_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
14020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&dks, (unsigned char *)iv->v, IDEA_DECRYPT);
14030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
14050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
14080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_idea_weakkey(key)
14090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
14100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;       /* XXX */
14120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
14150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_idea_keylen(len)
14160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
14170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != 0 && len != 128)
14190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
14200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 128;
14210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
14230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
14250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * BLOWFISH-CBC
14260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
14270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
14280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_bf_encrypt(data, key, iv)
14290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
14300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_bf_cbc(), 1);
14320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
14350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_bf_decrypt(data, key, iv)
14360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
14370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_bf_cbc(), 0);
14390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
14420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_bf_weakkey(key)
14430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
14440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;	/* XXX to be done. refer to RFC 2451 */
14460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
14490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_bf_keylen(len)
14500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
14510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0)
14530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 448;
14540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len < 40 || len > 448)
14550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
14560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return len;
14570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_RC5_H
14600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
14610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * RC5-CBC
14620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
14630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
14640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_rc5_encrypt(data, key, iv)
14650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
14660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
14680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RC5_32_KEY ks;
14690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* in RFC 2451, there is information about the number of round. */
14710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RC5_32_set_key(&ks, key->l, (unsigned char *)key->v, 16);
14720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for result */
14740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
14750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
14760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* decryption data */
14780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RC5_32_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
14790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		&ks, (unsigned char *)iv->v, RC5_ENCRYPT);
14800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
14820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
14850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_rc5_decrypt(data, key, iv)
14860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
14870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
14890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RC5_32_KEY ks;
14900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* in RFC 2451, there is information about the number of round. */
14920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RC5_32_set_key(&ks, key->l, (unsigned char *)key->v, 16);
14930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for result */
14950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
14960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
14970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* decryption data */
14990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RC5_32_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
15000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		&ks, (unsigned char *)iv->v, RC5_DECRYPT);
15010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
15030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_rc5_weakkey(key)
15070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
15080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;       /* No known weak keys when used with 16 rounds. */
15100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_rc5_keylen(len)
15150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
15160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0)
15180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 128;
15190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len < 40 || len > 2040)
15200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
15210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return len;
15220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
15240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
15260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3DES-CBC
15270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
15280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
15290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_3des_encrypt(data, key, iv)
15300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
15310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 1);
15330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
15360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_3des_decrypt(data, key, iv)
15370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
15380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 0);
15400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_3des_weakkey(key)
15440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
15450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef USE_NEW_DES_API
15470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return (DES_is_weak_key((void *)key->v) ||
15480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    DES_is_weak_key((void *)(key->v + 8)) ||
15490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    DES_is_weak_key((void *)(key->v + 16)));
15500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
15510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (key->l < 24)
15520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
15530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return (des_is_weak_key((void *)key->v) ||
15550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    des_is_weak_key((void *)(key->v + 8)) ||
15560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    des_is_weak_key((void *)(key->v + 16)));
15570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
15580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_3des_keylen(len)
15620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
15630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != 0 && len != 192)
15650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
15660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 192;
15670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
15700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * CAST-CBC
15710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
15720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
15730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_cast_encrypt(data, key, iv)
15740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
15750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_cast5_cbc(), 1);
15770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
15800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_cast_decrypt(data, key, iv)
15810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
15820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_cast5_cbc(), 0);
15840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_cast_weakkey(key)
15880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
15890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;	/* No known weak keys. */
15910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_cast_keylen(len)
15950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
15960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0)
15980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 128;
15990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len < 40 || len > 128)
16000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
16010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return len;
16020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
16050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * AES(RIJNDAEL)-CBC
16060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
16070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef HAVE_OPENSSL_AES_H
16080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
16090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_aes_encrypt(data, key, iv)
16100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
16110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
16130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	keyInstance k;
16140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	cipherInstance c;
16150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&k, 0, sizeof(k));
16170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rijndael_makeKey(&k, DIR_ENCRYPT, key->l << 3, key->v) < 0)
16180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for result */
16210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
16220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* encryption data */
16250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&c, 0, sizeof(c));
16260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rijndael_cipherInit(&c, MODE_CBC, iv->v) < 0){
16270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
16280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rijndael_blockEncrypt(&c, &k, data->v, data->l << 3, res->v) < 0){
16310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
16320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
16360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
16390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_aes_decrypt(data, key, iv)
16400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
16410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
16430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	keyInstance k;
16440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	cipherInstance c;
16450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&k, 0, sizeof(k));
16470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rijndael_makeKey(&k, DIR_DECRYPT, key->l << 3, key->v) < 0)
16480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for result */
16510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
16520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* decryption data */
16550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&c, 0, sizeof(c));
16560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rijndael_cipherInit(&c, MODE_CBC, iv->v) < 0){
16570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
16580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rijndael_blockDecrypt(&c, &k, data->v, data->l << 3, res->v) < 0){
16610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
16620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
16660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
16680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic inline const EVP_CIPHER *
16690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangaes_evp_by_keylen(int keylen)
16700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch(keylen) {
16720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 16:
16730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 128:
16740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return EVP_aes_128_cbc();
16750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 24:
16760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 192:
16770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return EVP_aes_192_cbc();
16780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 32:
16790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 256:
16800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return EVP_aes_256_cbc();
16810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
16820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
16830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
16870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_aes_encrypt(data, key, iv)
16880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang       vchar_t *data, *key, *iv;
16890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 1);
16910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
16940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_aes_decrypt(data, key, iv)
16950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang       vchar_t *data, *key, *iv;
16960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 0);
16980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
17000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_aes_weakkey(key)
17030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
17040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
17060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_aes_keylen(len)
17100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
17110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0)
17130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 128;
17140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != 128 && len != 192 && len != 256)
17150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
17160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return len;
17170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if defined(HAVE_OPENSSL_CAMELLIA_H)
17200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
17210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * CAMELLIA-CBC
17220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
17230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic inline const EVP_CIPHER *
17240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcamellia_evp_by_keylen(int keylen)
17250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch(keylen) {
17270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 16:
17280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 128:
17290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return EVP_camellia_128_cbc();
17300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 24:
17310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 192:
17320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return EVP_camellia_192_cbc();
17330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 32:
17340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 256:
17350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return EVP_camellia_256_cbc();
17360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
17370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
17380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
17420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_camellia_encrypt(data, key, iv)
17430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang       vchar_t *data, *key, *iv;
17440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, camellia_evp_by_keylen(key->l), 1);
17460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
17490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_camellia_decrypt(data, key, iv)
17500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang       vchar_t *data, *key, *iv;
17510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, camellia_evp_by_keylen(key->l), 0);
17530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_camellia_weakkey(key)
17570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
17580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
17600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_camellia_keylen(len)
17640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
17650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0)
17670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 128;
17680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != 128 && len != 192 && len != 256)
17690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
17700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return len;
17710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
17740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* for ipsec part */
17760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_null_hashlen()
17780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
17800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_kpdk_hashlen()
17840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
17860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_twofish_keylen(len)
17900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
17910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len < 0 || len > 256)
17930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
17940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return len;
17950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_null_keylen(len)
17990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
18000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
18020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HMAC functions
18060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic caddr_t
18080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmac_init(key, md)
18090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
18100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const EVP_MD *md;
18110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_CTX *c = racoon_malloc(sizeof(*c));
18130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Init(c, key->v, key->l, md);
18150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return (caddr_t)c;
18170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef WITH_SHA2
18200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HMAC SHA2-512
18220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
18240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_512_one(key, data)
18250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key, *data;
18260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1827c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
1828c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
1829c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1830c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_hmacsha2_512_init(key);
1831c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_hmacsha2_512_update(ctx, data);
1832c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_hmacsha2_512_final(ctx);
1833c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1834c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
18350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
18380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_512_init(key)
18390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
18400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_hmac_init(key, EVP_sha2_512());
18420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
18450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_512_update(c, data)
18460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
18470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
18480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
18500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
18530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_512_final(c)
18540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
18550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
18570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int l;
18580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0)
18600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
18610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
18630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res->l = l;
18640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_cleanup((HMAC_CTX *)c);
18650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
18660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (SHA512_DIGEST_LENGTH != res->l) {
18680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"hmac sha2_512 length mismatch %zd.\n", res->l);
18700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
18710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
18720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
18750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HMAC SHA2-384
18790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
18810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_384_one(key, data)
18820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key, *data;
18830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1884c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
1885c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
1886c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1887c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_hmacsha2_384_init(key);
1888c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_hmacsha2_384_update(ctx, data);
1889c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_hmacsha2_384_final(ctx);
1890c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1891c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
18920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
18950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_384_init(key)
18960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
18970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_hmac_init(key, EVP_sha2_384());
18990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
19020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_384_update(c, data)
19030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
19040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
19050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
19070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
19100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_384_final(c)
19110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
19120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
19140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int l;
19150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0)
19170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
19180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
19200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res->l = l;
19210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_cleanup((HMAC_CTX *)c);
19220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
19230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (SHA384_DIGEST_LENGTH != res->l) {
19250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"hmac sha2_384 length mismatch %zd.\n", res->l);
19270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
19280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
19290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
19320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
19350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HMAC SHA2-256
19360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
19370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
19380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_256_one(key, data)
19390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key, *data;
19400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1941c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
1942c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
1943c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1944c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_hmacsha2_256_init(key);
1945c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_hmacsha2_256_update(ctx, data);
1946c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_hmacsha2_256_final(ctx);
1947c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1948c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
19490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
19520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_256_init(key)
19530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
19540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_hmac_init(key, EVP_sha2_256());
19560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
19590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_256_update(c, data)
19600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
19610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
19620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
19640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
19670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_256_final(c)
19680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
19690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
19710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int l;
19720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0)
19740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
19750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
19770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res->l = l;
19780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_cleanup((HMAC_CTX *)c);
19790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
19800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (SHA256_DIGEST_LENGTH != res->l) {
19820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"hmac sha2_256 length mismatch %zd.\n", res->l);
19840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
19850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
19860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
19890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif	/* WITH_SHA2 */
19910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
19930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HMAC SHA1
19940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
19950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
19960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha1_one(key, data)
19970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key, *data;
19980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1999c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2000c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2001c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2002c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_hmacsha1_init(key);
2003c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_hmacsha1_update(ctx, data);
2004c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_hmacsha1_final(ctx);
2005c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2006c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
20070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
20100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha1_init(key)
20110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
20120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_hmac_init(key, EVP_sha1());
20140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
20170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha1_update(c, data)
20180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
20190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
20200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
20220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
20250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha1_final(c)
20260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
20270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
20290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int l;
20300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0)
20320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
20330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
20350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res->l = l;
20360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_cleanup((HMAC_CTX *)c);
20370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
20380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (SHA_DIGEST_LENGTH != res->l) {
20400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
20410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"hmac sha1 length mismatch %zd.\n", res->l);
20420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
20430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
20440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
20470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
20500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HMAC MD5
20510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
20520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
20530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacmd5_one(key, data)
20540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key, *data;
20550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2056c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2057c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2058c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2059c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_hmacmd5_init(key);
2060c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_hmacmd5_update(ctx, data);
2061c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_hmacmd5_final(ctx);
2062c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2063c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
20640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
20670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacmd5_init(key)
20680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
20690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_hmac_init(key, EVP_md5());
20710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
20740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacmd5_update(c, data)
20750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
20760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
20770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
20790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
20820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacmd5_final(c)
20830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
20840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
20860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int l;
20870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0)
20890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
20900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
20920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res->l = l;
20930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_cleanup((HMAC_CTX *)c);
20940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
20950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (MD5_DIGEST_LENGTH != res->l) {
20970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
20980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"hmac md5 length mismatch %zd.\n", res->l);
20990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
21000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
21010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
21040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef WITH_SHA2
21070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
21080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SHA2-512 functions
21090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
21100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
21110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_512_init()
21120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA512_CTX *c = racoon_malloc(sizeof(*c));
21140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA512_Init(c);
21160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return((caddr_t)c);
21180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
21210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_512_update(c, data)
21220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
21230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
21240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA512_Update((SHA512_CTX *)c, (unsigned char *) data->v, data->l);
21260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
21280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
21310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_512_final(c)
21320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
21330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
21350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0)
21370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(0);
21380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA512_Final((unsigned char *) res->v, (SHA512_CTX *)c);
21400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
21410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
21430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
21460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_512_one(data)
21470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
21480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2149c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2150c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2151c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2152c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_sha2_512_init();
2153c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_sha2_512_update(ctx, data);
2154c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_sha2_512_final(ctx);
2155c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2156c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
21570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
21600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_512_hashlen()
21610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return SHA512_DIGEST_LENGTH << 3;
21630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
21650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef WITH_SHA2
21670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
21680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SHA2-384 functions
21690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
21700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
21710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_384_init()
21720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA384_CTX *c = racoon_malloc(sizeof(*c));
21740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA384_Init(c);
21760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return((caddr_t)c);
21780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
21810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_384_update(c, data)
21820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
21830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
21840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA384_Update((SHA384_CTX *)c, (unsigned char *) data->v, data->l);
21860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
21880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
21910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_384_final(c)
21920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
21930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
21950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0)
21970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(0);
21980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA384_Final((unsigned char *) res->v, (SHA384_CTX *)c);
22000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
22010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
22030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
22060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_384_one(data)
22070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
22080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2209c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2210c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2211c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2212c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_sha2_384_init();
2213c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_sha2_384_update(ctx, data);
2214c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_sha2_384_final(ctx);
2215c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2216c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
22170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
22200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_384_hashlen()
22210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return SHA384_DIGEST_LENGTH << 3;
22230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
22250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef WITH_SHA2
22270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
22280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SHA2-256 functions
22290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
22300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
22310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_256_init()
22320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA256_CTX *c = racoon_malloc(sizeof(*c));
22340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA256_Init(c);
22360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return((caddr_t)c);
22380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
22410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_256_update(c, data)
22420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
22430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
22440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA256_Update((SHA256_CTX *)c, (unsigned char *) data->v, data->l);
22460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
22480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
22510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_256_final(c)
22520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
22530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
22550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0)
22570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(0);
22580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA256_Final((unsigned char *) res->v, (SHA256_CTX *)c);
22600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
22610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
22630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
22660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_256_one(data)
22670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
22680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2269c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2270c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2271c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2272c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_sha2_256_init();
2273c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_sha2_256_update(ctx, data);
2274c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_sha2_256_final(ctx);
2275c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2276c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
22770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
22800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_256_hashlen()
22810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return SHA256_DIGEST_LENGTH << 3;
22830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
22850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
22870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SHA functions
22880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
22890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
22900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha1_init()
22910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA_CTX *c = racoon_malloc(sizeof(*c));
22930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA1_Init(c);
22950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return((caddr_t)c);
22970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
23000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha1_update(c, data)
23010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
23020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
23030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA1_Update((SHA_CTX *)c, data->v, data->l);
23050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
23070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
23100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha1_final(c)
23110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
23120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
23140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0)
23160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(0);
23170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA1_Final((unsigned char *) res->v, (SHA_CTX *)c);
23190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
23200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
23220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
23250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha1_one(data)
23260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
23270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2328c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2329c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2330c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2331c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_sha1_init();
2332c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_sha1_update(ctx, data);
2333c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_sha1_final(ctx);
2334c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2335c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
23360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
23390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha1_hashlen()
23400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return SHA_DIGEST_LENGTH << 3;
23420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
23450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * MD5 functions
23460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
23470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
23480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_md5_init()
23490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	MD5_CTX *c = racoon_malloc(sizeof(*c));
23510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	MD5_Init(c);
23530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return((caddr_t)c);
23550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
23580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_md5_update(c, data)
23590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
23600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
23610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	MD5_Update((MD5_CTX *)c, data->v, data->l);
23630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
23650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
23680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_md5_final(c)
23690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
23700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
23720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0)
23740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(0);
23750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	MD5_Final((unsigned char *) res->v, (MD5_CTX *)c);
23770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
23780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
23800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
23830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_md5_one(data)
23840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
23850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2386c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2387c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2388c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2389c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_md5_init();
2390c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_md5_update(ctx, data);
2391c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_md5_final(ctx);
2392c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2393c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
23940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
23970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_md5_hashlen()
23980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return MD5_DIGEST_LENGTH << 3;
24000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
24030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * eay_set_random
24040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *   size: number of bytes.
24050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
24060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
24070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_set_random(size)
24080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t size;
24090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *r = NULL;
24110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res = 0;
24120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((r = BN_new()) == NULL)
24140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BN_rand(r, size * 8, 0, 0);
24160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	eay_bn2v(&res, r);
24170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
24190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (r)
24200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		BN_free(r);
24210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
24220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* DH */
24250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
24260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_dh_generate(prime, g, publen, pub, priv)
24270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *prime, **pub, **priv;
24280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int publen;
24290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t g;
24300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *p = NULL;
24320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	DH *dh = NULL;
24330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
24340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* initialize */
24360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* pre-process to generate number */
24370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_v2bn(&p, prime) < 0)
24380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((dh = DH_new()) == NULL)
24410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dh->p = p;
24430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = NULL;	/* p is now part of dh structure */
24440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dh->g = NULL;
24450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((dh->g = BN_new()) == NULL)
24460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!BN_set_word(dh->g, g))
24480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (publen != 0)
24510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dh->length = publen;
24520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* generate public and private number */
24540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!DH_generate_key(dh))
24550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy results to buffers */
24580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_bn2v(pub, dh->pub_key) < 0)
24590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_bn2v(priv, dh->priv_key) < 0) {
24610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(*pub);
24620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
24660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
24680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (dh != NULL)
24690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		DH_free(dh);
24700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (p != 0)
24710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		BN_free(p);
24720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(error);
24730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
24760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_dh_compute(prime, g, pub, priv, pub2, key)
24770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *prime, *pub, *priv, *pub2, **key;
24780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t g;
24790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *dh_pub = NULL;
24810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	DH *dh = NULL;
24820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int l;
24830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned char *v = NULL;
24840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
24850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make public number to compute */
24870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_v2bn(&dh_pub, pub2) < 0)
24880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make DH structure */
24910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((dh = DH_new()) == NULL)
24920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_v2bn(&dh->p, prime) < 0)
24940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_v2bn(&dh->pub_key, pub) < 0)
24960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_v2bn(&dh->priv_key, priv) < 0)
24980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dh->length = pub2->l * 8;
25000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dh->g = NULL;
25020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((dh->g = BN_new()) == NULL)
25030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!BN_set_word(dh->g, g))
25050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((v = racoon_calloc(prime->l, sizeof(u_char))) == NULL)
25080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((l = DH_compute_key(v, dh_pub, dh)) == -1)
25100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy((*key)->v + (prime->l - l), v, l);
25120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
25140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
25160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (dh_pub != NULL)
25170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		BN_free(dh_pub);
25180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (dh != NULL)
25190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		DH_free(dh);
25200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (v != NULL)
25210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(v);
25220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(error);
25230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
25260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * convert vchar_t <-> BIGNUM.
25270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
25280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * vchar_t: unit is u_char, network endian, most significant byte first.
25290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * BIGNUM: unit is BN_ULONG, each of BN_ULONG is in host endian,
25300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	least significant BN_ULONG must come first.
25310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
25320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * hex value of "0x3ffe050104" is represented as follows:
25330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	vchar_t: 3f fe 05 01 04
25340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	BIGNUM (BN_ULONG = u_int8_t): 04 01 05 fe 3f
25350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	BIGNUM (BN_ULONG = u_int16_t): 0x0104 0xfe05 0x003f
25360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	BIGNUM (BN_ULONG = u_int32_t_t): 0xfe050104 0x0000003f
25370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
25380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
25390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_v2bn(bn, var)
25400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM **bn;
25410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *var;
25420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
25430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((*bn = BN_bin2bn((unsigned char *) var->v, var->l, NULL)) == NULL)
25440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
25470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
25500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_bn2v(var, bn)
25510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t **var;
25520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *bn;
25530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
25540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*var = vmalloc(bn->top * BN_BYTES);
25550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*var == NULL)
25560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(-1);
25570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(*var)->l = BN_bn2bin(bn, (unsigned char *) (*var)->v);
25590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
25610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
25640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_init()
25650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
25660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	OpenSSL_add_all_algorithms();
25670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ERR_load_crypto_strings();
25680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_ENGINE_H
25690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ENGINE_load_builtin_engines();
25700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ENGINE_register_all_complete();
25710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
25720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
25750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbase64_decode(char *in, long inlen)
25760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
25770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO *bio=NULL, *b64=NULL;
25780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res = NULL;
25790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *outb;
25800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	long outlen;
25810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	outb = malloc(inlen * 2);
25830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (outb == NULL)
25840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
25850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bio = BIO_new_mem_buf(in, inlen);
25860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	b64 = BIO_new(BIO_f_base64());
25870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
25880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bio = BIO_push(b64, bio);
25890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	outlen = BIO_read(bio, outb, inlen * 2);
25910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (outlen <= 0) {
25920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
25930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
25940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = vmalloc(outlen);
25970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!res)
25980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
25990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(res->v, outb, outlen);
26010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
26030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (outb)
26040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		free(outb);
26050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bio)
26060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		BIO_free_all(bio);
26070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
26090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
26120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbase64_encode(char *in, long inlen)
26130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO *bio=NULL, *b64=NULL;
26150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *ptr;
26160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	long plen = -1;
26170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res = NULL;
26180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bio = BIO_new(BIO_s_mem());
26200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	b64 = BIO_new(BIO_f_base64());
26210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
26220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bio = BIO_push(b64, bio);
26230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO_write(bio, in, inlen);
26250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO_flush(bio);
26260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plen = BIO_get_mem_data(bio, &ptr);
26280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = vmalloc(plen+1);
26290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!res)
26300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
26310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy (res->v, ptr, plen);
26330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res->v[plen] = '\0';
26340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
26360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bio)
26370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		BIO_free_all(bio);
26380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
26400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic RSA *
26430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbinbuf_pubkey2rsa(vchar_t *binbuf)
26440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *exp, *mod;
26460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RSA *rsa_pub = NULL;
26470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (binbuf->v[0] > binbuf->l - 1) {
26490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: decoded string doesn't make sense.\n");
26500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
26510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	exp = BN_bin2bn((unsigned char *) (binbuf->v + 1), binbuf->v[0], NULL);
26540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	mod = BN_bin2bn((unsigned char *) (binbuf->v + binbuf->v[0] + 1),
26550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			binbuf->l - binbuf->v[0] - 1, NULL);
26560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rsa_pub = RSA_new();
26570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!exp || !mod || !rsa_pub) {
26590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey parsing error: %s\n", eay_strerror());
26600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (exp)
26610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			BN_free(exp);
26620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (mod)
26630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			BN_free(exp);
26640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (rsa_pub)
26650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			RSA_free(rsa_pub);
26660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		rsa_pub = NULL;
26670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
26680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rsa_pub->n = mod;
26710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rsa_pub->e = exp;
26720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
26740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return rsa_pub;
26750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangRSA *
26780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbase64_pubkey2rsa(char *in)
26790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *exp, *mod;
26810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RSA *rsa_pub = NULL;
26820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *binbuf;
26830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (strncmp(in, "0s", 2) != 0) {
26850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: doesn't start with '0s'\n");
26860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
26870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	binbuf = base64_decode(in + 2, strlen(in + 2));
26900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!binbuf) {
26910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: Base64 decoding failed.\n");
26920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
26930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (binbuf->v[0] > binbuf->l - 1) {
26960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: decoded string doesn't make sense.\n");
26970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
26980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rsa_pub = binbuf_pubkey2rsa(binbuf);
27010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
27030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (binbuf)
27040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(binbuf);
27050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return rsa_pub;
27070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangRSA *
27100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbignum_pubkey2rsa(BIGNUM *in)
27110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RSA *rsa_pub = NULL;
27130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *binbuf;
27140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	binbuf = vmalloc(BN_num_bytes(in));
27160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!binbuf) {
27170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey conversion: memory allocation failed..\n");
27180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
27190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BN_bn2bin(in, (unsigned char *) binbuf->v);
27220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rsa_pub = binbuf_pubkey2rsa(binbuf);
27240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
27260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (binbuf)
27270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(binbuf);
27280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return rsa_pub;
27300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangu_int32_t
27330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_random()
27340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t result;
27360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *vrand;
27370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vrand = eay_set_random(sizeof(result));
27390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&result, vrand->v, sizeof(result));
27400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(vrand);
27410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return result;
27430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangconst char *
27460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_version()
27470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return SSLeay_version(SSLEAY_VERSION);
27490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
2750