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
116a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(OPENSSL_IS_BORINGSSL)
117a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley/* HMAC_cleanup is deprecated wrapper in OpenSSL and has been removed in
118a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley * BoringSSL. */
119a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx)
120a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
121a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley
1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * I hate to cast every parameter to des_xx into void *, but it is
1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * necessary for SSLeay/OpenSSL portability.  It sucks.
1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int cb_check_cert_local __P((int, X509_STORE_CTX *));
1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int cb_check_cert_remote __P((int, X509_STORE_CTX *));
1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic X509 *mem2x509 __P((vchar_t *));
1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic caddr_t eay_hmac_init __P((vchar_t *, const EVP_MD *));
1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* X509 Certificate */
1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * convert the string of the subject name into DER
1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * e.g. str = "C=JP, ST=Kanagawa";
1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_str2asn1dn(str, len)
1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const char *str;
1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_NAME *name;
144c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	char *buf;
1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *field, *value;
146c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int i, j;
1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *ret = NULL;
1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t p;
1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == -1)
1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = strlen(str);
1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf = racoon_malloc(len + 1);
1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!buf) {
1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n");
1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(buf, str, len);
1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	name = X509_NAME_new();
1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
162c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	field = &buf[0];
1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	value = NULL;
1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < len; i++) {
1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!value && buf[i] == '=') {
166c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			buf[i] = '\0';
167c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			value = &buf[i + 1];
1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else if (buf[i] == ',' || buf[i] == '/') {
170c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			buf[i] = '\0';
1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n",
1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     field, value);
1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!value) goto err;
1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!X509_NAME_add_entry_by_txt(name, field,
1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					(value[0] == '*' && value[1] == 0) ?
1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						V_ASN1_PRINTABLESTRING : MBSTRING_ASC,
1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					(unsigned char *) value, -1, -1, 0)) {
1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     "Invalid DN field: %s=%s\n",
1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     field, value);
1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     "%s\n", eay_strerror());
1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err;
1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
187c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			for (j = i + 1; j < len; j++) {
188c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				if (buf[j] != ' ')
189c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					break;
190c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
191c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			field = &buf[j];
1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			value = NULL;
1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
196c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	buf[len] = '\0';
1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n",
1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	     field, value);
2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!value) goto err;
2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!X509_NAME_add_entry_by_txt(name, field,
2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(value[0] == '*' && value[1] == 0) ?
2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				V_ASN1_PRINTABLESTRING : MBSTRING_ASC,
2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(unsigned char *) value, -1, -1, 0)) {
2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     "Invalid DN field: %s=%s\n",
2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     field, value);
2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     "%s\n", eay_strerror());
2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	i = i2d_X509_NAME(name, NULL);
2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!i)
2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = vmalloc(i);
2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!ret)
2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = ret->v;
2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	i = i2d_X509_NAME(name, (void *)&p);
2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!i)
2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ret;
2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    err:
2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf)
2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(buf);
2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (name)
2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_NAME_free(name);
2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ret)
2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(ret);
2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * convert the hex string of the subject name into DER
2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hex2asn1dn(const char *hex, int len)
2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *bn = BN_new();
2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *binbuf;
2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t binlen;
2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *ret = NULL;
2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == -1)
2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = strlen(hex);
2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (BN_hex2bn(&bn, hex) != len) {
2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     "conversion of Hex-encoded ASN1 string to binary failed: %s\n",
2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     eay_strerror());
2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	binlen = BN_num_bytes(bn);
2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = vmalloc(binlen);
2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!ret) {
2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n");
2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	binbuf = ret->v;
2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BN_bn2bin(bn, (unsigned char *) binbuf);
2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BN_free(bn);
2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ret;
2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * The following are derived from code in crypto/x509/x509_cmp.c
2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * in OpenSSL0.9.7c:
2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * X509_NAME_wildcmp() adds wildcard matching to the original
2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * X509_NAME_cmp(), nocase_cmp() and nocase_spacenorm_cmp() are as is.
2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <ctype.h>
2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Case insensitive string comparision */
2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (a->length != b->length)
2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return (a->length - b->length);
2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i=0; i<a->length; i++)
2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int ca, cb;
2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ca = tolower(a->data[i]);
2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		cb = tolower(b->data[i]);
2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ca != cb)
2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return(ca-cb);
2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Case insensitive string comparision with space normalization
3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Space normalization - ignore leading, trailing spaces,
3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *       multiple spaces between characters are replaced by single space
3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned char *pa = NULL, *pb = NULL;
3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int la, lb;
3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	la = a->length;
3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lb = b->length;
3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pa = a->data;
3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pb = b->data;
3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* skip leading spaces */
3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (la > 0 && isspace(*pa))
3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		la--;
3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pa++;
3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (lb > 0 && isspace(*pb))
3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		lb--;
3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pb++;
3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* skip trailing spaces */
3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (la > 0 && isspace(pa[la-1]))
3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		la--;
3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (lb > 0 && isspace(pb[lb-1]))
3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		lb--;
3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* compare strings with space normalization */
3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (la > 0 && lb > 0)
3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int ca, cb;
3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* compare character */
3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ca = tolower(*pa);
3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		cb = tolower(*pb);
3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ca != cb)
3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return (ca - cb);
3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pa++; pb++;
3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		la--; lb--;
3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (la <= 0 || lb <= 0)
3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* is white space next character ? */
3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isspace(*pa) && isspace(*pb))
3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* skip remaining white spaces */
3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			while (la > 0 && isspace(*pa))
3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			{
3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				la--;
3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pa++;
3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			while (lb > 0 && isspace(*pb))
3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			{
3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				lb--;
3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pb++;
3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (la > 0 || lb > 0)
3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return la - lb;
3690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int X509_NAME_wildcmp(const X509_NAME *a, const X509_NAME *b)
3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    int i,j;
3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    X509_NAME_ENTRY *na,*nb;
3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    if (sk_X509_NAME_ENTRY_num(a->entries)
3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	!= sk_X509_NAME_ENTRY_num(b->entries))
3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    return sk_X509_NAME_ENTRY_num(a->entries)
3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	      -sk_X509_NAME_ENTRY_num(b->entries);
3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    na=sk_X509_NAME_ENTRY_value(a->entries,i);
3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    nb=sk_X509_NAME_ENTRY_value(b->entries,i);
3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    j=OBJ_cmp(na->object,nb->object);
3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    if (j) return(j);
3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    if ((na->value->length == 1 && na->value->data[0] == '*')
3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	     || (nb->value->length == 1 && nb->value->data[0] == '*'))
3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    continue;
3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    j=na->value->type-nb->value->type;
3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    if (j) return(j);
3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    if (na->value->type == V_ASN1_PRINTABLESTRING)
3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    j=nocase_spacenorm_cmp(na->value, nb->value);
3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    else if (na->value->type == V_ASN1_IA5STRING
3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    j=nocase_cmp(na->value, nb->value);
3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    else
3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    {
4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    j=na->value->length-nb->value->length;
4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    if (j) return(j);
4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    j=memcmp(na->value->data,nb->value->data,
4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    na->value->length);
4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    }
4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    if (j) return(j);
4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    j=na->set-nb->set;
4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    if (j) return(j);
4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    return(0);
4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * compare two subjectNames.
4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT:        0: equal
4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	positive:
4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	      -1: other error.
4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_cmp_asn1dn(n1, n2)
4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *n1, *n2;
4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_NAME *a = NULL, *b = NULL;
4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t p;
4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i = -1;
4260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = n1->v;
4280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!d2i_X509_NAME(&a, (void *)&p, n1->l))
4290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
4300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = n2->v;
4310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!d2i_X509_NAME(&b, (void *)&p, n2->l))
4320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	i = X509_NAME_wildcmp(a, b);
4350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    end:
4370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (a)
4380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_NAME_free(a);
4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (b)
4400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_NAME_free(b);
4410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return i;
4420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
4430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
444b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh#ifdef ANDROID_CHANGES
445e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh
446e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yehstatic BIO *BIO_from_android(char *path)
447c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{
448e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	void *data;
4498f3b38855d8849959825acc45dd11144adc7d862Chia-chi Yeh	if (sscanf(path, pname, &data) == 1) {
450e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		return BIO_new_mem_buf(data, -1);
451b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh	}
452e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	return NULL;
453b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh}
454b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh
455e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#endif
456b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh
4570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
4580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this functions is derived from apps/verify.c in OpenSSL0.9.5
4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
4610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_check_x509cert(cert, CApath, CAfile, local)
4620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
4630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *CApath;
4640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *CAfile;
4650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int local;
4660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE *cert_ctx = NULL;
4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_LOOKUP *lookup = NULL;
4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509 = NULL;
4700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE_CTX *csc;
4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	cert_ctx = X509_STORE_new();
4740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (cert_ctx == NULL)
4750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
4760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (local)
4780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_local);
4790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
4800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_remote);
4810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
482e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#ifdef ANDROID_CHANGES
4838f3b38855d8849959825acc45dd11144adc7d862Chia-chi Yeh	if (pname) {
484fd76ec530c3f9cd0b9cc03501d02b6cb3ba705edChia-chi Yeh		BIO *bio = BIO_from_android(CAfile);
4855cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		STACK_OF(X509_INFO) *stack;
4865cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		X509_INFO *info;
4875cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		int i;
4885cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh
4895cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		if (!bio) {
4905cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			goto end;
4915cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		}
4925cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
4935cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		BIO_free(bio);
4945cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		if (!stack) {
4955cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			goto end;
4965cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		}
4975cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		for (i = 0; i < sk_X509_INFO_num(stack); ++i) {
4985cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			info = sk_X509_INFO_value(stack, i);
4995cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			if (info->x509) {
5005cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh				X509_STORE_add_cert(cert_ctx, info->x509);
5015cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			}
5025cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			if (info->crl) {
5035cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh				X509_STORE_add_crl(cert_ctx, info->crl);
5045cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh			}
505b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh		}
5065cbb57af3a64593fc4bfbb2c42c3d24553e8bae4Chia-chi Yeh		sk_X509_INFO_pop_free(stack, X509_INFO_free);
507e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	} else {
508e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#endif
509e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
510e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	if (lookup == NULL)
511e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		goto end;
512e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh
513e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	X509_LOOKUP_load_file(lookup, CAfile,
514e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	    (CAfile == NULL) ? X509_FILETYPE_DEFAULT : X509_FILETYPE_PEM);
515e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh
516e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
517e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	if (lookup == NULL)
518e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		goto end;
519e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	error = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM);
520e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	if(!error) {
521e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		error = -1;
522e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		goto end;
523e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	}
524e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	error = -1;	/* initialized */
525e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#ifdef ANDROID_CHANGES
526b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh	}
527b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh#endif
5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* read the certificate to be verified */
5300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = mem2x509(cert);
5310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 == NULL)
5320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
5330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	csc = X509_STORE_CTX_new();
5350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (csc == NULL)
5360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
5370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE_CTX_init(csc, cert_ctx, x509, NULL);
5380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK);
5400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK_ALL);
5410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = X509_verify_cert(csc);
543051f86dfca525c160855397f7b6a4fb5ef8df2b5Chia-chi Yeh	X509_STORE_CTX_free(csc);
5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * if x509_verify_cert() is successful then the value of error is
5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * set non-zero.
5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
5490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = error ? 0 : -1;
5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error)
5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,"%s\n", eay_strerror());
5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (cert_ctx != NULL)
5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_STORE_free(cert_ctx);
5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 != NULL)
5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_free(x509);
5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(error);
5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * callback function for verifing certificate.
5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function is derived from cb() in openssl/apps/s_server.c
5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcb_check_cert_local(ok, ctx)
5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ok;
5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE_CTX *ctx;
5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char buf[256];
5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int log_tag;
5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!ok) {
5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_NAME_oneline(
5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				X509_get_subject_name(ctx->current_cert),
5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				buf,
5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				256);
5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * since we are just checking the certificates, it is
5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * ok if they are self signed. But we should still warn
5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * the user.
5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 		 */
5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (ctx->error) {
5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_CERT_HAS_EXPIRED:
5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_INVALID_CA:
5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_PATH_LENGTH_EXCEEDED:
5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_INVALID_PURPOSE:
5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_UNABLE_TO_GET_CRL:
5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ok = 1;
5920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			log_tag = LLV_WARNING;
5930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			log_tag = LLV_ERROR;
5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(log_tag, LOCATION, NULL,
5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s(%d) at depth:%d SubjectName:%s\n",
5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_verify_cert_error_string(ctx->error),
6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ctx->error,
6010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ctx->error_depth,
6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			buf);
6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ERR_clear_error();
6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ok;
6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * callback function for verifing remote certificates.
6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function is derived from cb() in openssl/apps/s_server.c
6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcb_check_cert_remote(ok, ctx)
6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ok;
6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_STORE_CTX *ctx;
6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char buf[256];
6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int log_tag;
6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!ok) {
6220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_NAME_oneline(
6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				X509_get_subject_name(ctx->current_cert),
6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				buf,
6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				256);
6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (ctx->error) {
6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case X509_V_ERR_UNABLE_TO_GET_CRL:
6280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ok = 1;
6290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			log_tag = LLV_WARNING;
6300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
6320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			log_tag = LLV_ERROR;
6330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(log_tag, LOCATION, NULL,
6350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s(%d) at depth:%d SubjectName:%s\n",
6360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_verify_cert_error_string(ctx->error),
6370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ctx->error,
6380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ctx->error_depth,
6390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			buf);
6400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ERR_clear_error();
6420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ok;
6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
647c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * get a subjectAltName from X509 certificate.
6480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
6490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
6500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_x509asn1subjectname(cert)
6510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
6520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509 = NULL;
6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp;
6550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *name = NULL;
6560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
6570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
658c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	bp = (unsigned char *) cert->v;
659c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
6600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = mem2x509(cert);
6610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 == NULL)
6620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto error;
6630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get the length of the name */
6650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = i2d_X509_NAME(x509->cert_info->subject, NULL);
6660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	name = vmalloc(len);
6670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!name)
6680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto error;
6690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get the name */
6700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = (unsigned char *) name->v;
6710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = i2d_X509_NAME(x509->cert_info->subject, &bp);
6720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_free(x509);
6740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return name;
6760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerror:
6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
6790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (name != NULL)
6810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(name);
6820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 != NULL)
6840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_free(x509);
6850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
6900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get the subjectAltName from X509 certificate.
6910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * the name must be terminated by '\0'.
6920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
6930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
6940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_x509subjectaltname(cert, altname, type, pos)
6950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
6960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char **altname;
6970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *type;
6980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pos;
6990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509 = NULL;
7010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	GENERAL_NAMES *gens = NULL;
7020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	GENERAL_NAME *gen;
7030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
7050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*altname = NULL;
7070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*type = GENT_OTHERNAME;
7080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = mem2x509(cert);
7100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 == NULL)
7110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
7120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gens = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
7140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (gens == NULL)
7150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
7160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* there is no data at "pos" */
7180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pos > sk_GENERAL_NAME_num(gens))
7190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
7200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gen = sk_GENERAL_NAME_value(gens, pos - 1);
7220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* read DNSName / Email */
7240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (gen->type == GEN_DNS	||
7250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		gen->type == GEN_EMAIL	||
7260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		gen->type == GEN_URI )
7270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
7280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* make sure if the data is terminated by '\0'. */
7290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (gen->d.ia5->data[gen->d.ia5->length] != '\0')
7300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
7310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
7320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "data is not terminated by NUL.");
7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_hexdump(gen->d.ia5->data, gen->d.ia5->length + 1);
7340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
7350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = gen->d.ia5->length + 1;
7380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*altname = racoon_malloc(len);
7390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!*altname)
7400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
7410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		strlcpy(*altname, (char *) gen->d.ia5->data, len);
7430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*type = gen->type;
7440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		error = 0;
7450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* read IP address */
7470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else if (gen->type == GEN_IPADD)
7480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
7490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		unsigned char p[5], *ip;
7500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ip = p;
7510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* only support IPv4 */
7530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (gen->d.ip->length != 4)
7540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
7550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* convert Octet String to String
7570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * XXX ???????
7580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
7590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*i2d_ASN1_OCTET_STRING(gen->d.ip,&ip);*/
7600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ip = gen->d.ip->data;
7610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX Magic, enough for an IPv4 address
7630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
7640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*altname = racoon_malloc(20);
7650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!*altname)
7660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
7670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sprintf(*altname, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
7690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*type = gen->type;
7700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		error = 0;
7710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX other possible types ?
7730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * For now, error will be -1 if unsupported type
7740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
7750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
7770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error) {
7780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*altname) {
7790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(*altname);
7800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*altname = NULL;
7810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
7830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509)
7850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_free(x509);
7860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (gens)
7870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* free the whole stack. */
7880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
7910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
7950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * decode a X509 certificate and make a readable text terminated '\n'.
7960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * return the buffer allocated, so must free it later.
7970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *
7990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_x509text(cert)
8000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
8010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509 = NULL;
8030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO *bio = NULL;
8040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *text = NULL;
8050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp = NULL;
8060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0;
8070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
8080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = mem2x509(cert);
8100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 == NULL)
8110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bio = BIO_new(BIO_s_mem());
8140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bio == NULL)
8150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = X509_print(bio, x509);
8180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 1) {
8190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		error = -1;
8200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
823a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(ANDROID_CHANGES)
824a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	len = BIO_get_mem_data(bio, (char**) &bp);
825a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#else
8260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = BIO_get_mem_data(bio, &bp);
827a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
8280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	text = racoon_malloc(len + 1);
8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (text == NULL)
8300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(text, bp, len);
8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	text[len] = '\0';
8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
8350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    end:
8370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error) {
8380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (text) {
8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(text);
8400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			text = NULL;
8410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
8430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bio)
8450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		BIO_free(bio);
8460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509)
8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_free(x509);
8480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return text;
8500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* get X509 structure from buffer. */
8530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic X509 *
8540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangmem2x509(cert)
8550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
8560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509;
8580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef EAYDEBUG
8600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
8610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp;
8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
863c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	bp = (unsigned char *) cert->v;
8640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
865c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	x509 = d2i_X509(NULL, (void *)&bp, cert->l);
8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
8670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
8680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO *bio;
8700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
8710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bio = BIO_new(BIO_s_mem());
8730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bio == NULL)
8740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
875c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	len = BIO_write(bio, cert->v, cert->l);
8760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == -1)
8770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
8780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
8790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO_free(bio);
8800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
8810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return x509;
8830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
8860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get a X509 certificate from local file.
8870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * a certificate must be PEM format.
8880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Input:
8890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	path to a certificate.
8900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Output:
8910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	NULL if error occured
8920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	other is the cert.
8930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
8940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
8950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_x509cert(path)
8960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *path;
8970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	FILE *fp;
8990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509;
9000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
9010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp;
9020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
9030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
9040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
905b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh#ifdef ANDROID_CHANGES
9068f3b38855d8849959825acc45dd11144adc7d862Chia-chi Yeh	if (pname) {
907e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		BIO *bio = BIO_from_android(path);
908e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		if (!bio) {
909e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh			return NULL;
910e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		}
911b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh		x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
912b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh		BIO_free(bio);
913e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	} else {
914e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#endif
9150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Read private key */
9160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fp = fopen(path, "r");
9170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (fp == NULL)
9180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
9190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = PEM_read_X509(fp, NULL, NULL, NULL);
9200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fclose (fp);
921e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#ifdef ANDROID_CHANGES
922e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	}
923b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh#endif
9240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 == NULL)
9260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
9270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = i2d_X509(x509, NULL);
929c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	cert = vmalloc(len);
9300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (cert == NULL) {
9310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_free(x509);
9320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
9330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
934c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	bp = (unsigned char *) cert->v;
9350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = i2d_X509(x509, &bp);
9360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509_free(x509);
9370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error == 0) {
9390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(cert);
9400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
9410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return cert;
9440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
9470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check a X509 signature
9480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	XXX: to be get hash type from my cert ?
9490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *		to be handled EVP_dss().
9500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT: return -1 when error.
9510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0
9520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
9530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
9540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_check_x509sign(source, sig, cert)
9550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *source;
9560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sig;
9570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *cert;
9580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509;
960c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	u_char *bp;
9610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_PKEY *evp;
9620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int res;
9630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
964c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	bp = (unsigned char *) cert->v;
965c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
966c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	x509 = d2i_X509(NULL, (void *)&bp, cert->l);
967c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (x509 == NULL) {
968c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_ERROR, LOCATION, NULL, "d2i_X509(): %s\n", eay_strerror());
9690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
970c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
9710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	evp = X509_get_pubkey(x509);
9730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (! evp) {
9740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "X509_get_pubkey(): %s\n", eay_strerror());
9751c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		X509_free(x509);
9760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = eay_rsa_verify(source, sig, evp->pkey.rsa);
9800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_PKEY_free(evp);
9821c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	X509_free(x509);
9830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
9850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
9880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check RSA signature
9890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT: return -1 when error.
9900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0 on success
9910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
9920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
9930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_check_rsasign(source, sig, rsa)
9940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *source;
9950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sig;
9960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RSA *rsa;
9970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_rsa_verify(source, sig, rsa);
9990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
10020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get PKCS#1 Private Key of PEM format from local file.
10030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
10040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
10050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_pkcs1privkey(path)
10060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *path;
10070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	FILE *fp;
10090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_PKEY *evp = NULL;
10100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *pkey = NULL;
10110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp;
10120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pkeylen;
10130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
10140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1015b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh#ifdef ANDROID_CHANGES
10168f3b38855d8849959825acc45dd11144adc7d862Chia-chi Yeh	if (pname) {
1017e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		BIO *bio = BIO_from_android(path);
1018e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		if (!bio) {
1019e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh			return NULL;
1020e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh		}
1021b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh		evp = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
1022b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh		BIO_free(bio);
1023e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	} else {
1024e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#endif
10250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Read private key */
10260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fp = fopen(path, "r");
10270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (fp == NULL)
10280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
10290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	evp = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
10310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fclose (fp);
1033e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#ifdef ANDROID_CHANGES
1034e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh	}
1035b880c6609b0f748abe0ce19fea3b1b2fdfd991beChia-chi Yeh#endif
10360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (evp == NULL)
10380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
10390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pkeylen = i2d_PrivateKey(evp, NULL);
10410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkeylen == 0)
10420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
10430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pkey = vmalloc(pkeylen);
10440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkey == NULL)
10450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
10460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = (unsigned char *) pkey->v;
10470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pkeylen = i2d_PrivateKey(evp, &bp);
10480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkeylen == 0)
10490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
10500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
10520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
10540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (evp != NULL)
10550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		EVP_PKEY_free(evp);
10560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0 && pkey != NULL) {
10570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(pkey);
10580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pkey = NULL;
10590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return pkey;
10620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
10650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get PKCS#1 Public Key of PEM format from local file.
10660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
10670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
10680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_pkcs1pubkey(path)
10690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *path;
10700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	FILE *fp;
10720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_PKEY *evp = NULL;
10730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *pkey = NULL;
10740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	X509 *x509 = NULL;
10750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp;
10760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pkeylen;
10770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
10780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Read private key */
10800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fp = fopen(path, "r");
10810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (fp == NULL)
10820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
10830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	x509 = PEM_read_X509(fp, NULL, NULL, NULL);
10850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	fclose (fp);
10870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x509 == NULL)
10890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
10900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Get public key - eay */
10920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	evp = X509_get_pubkey(x509);
10930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (evp == NULL)
10940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
10950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pkeylen = i2d_PublicKey(evp, NULL);
10970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkeylen == 0)
10980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
10990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pkey = vmalloc(pkeylen);
11000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkey == NULL)
11010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
11020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = (unsigned char *) pkey->v;
11030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pkeylen = i2d_PublicKey(evp, &bp);
11040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkeylen == 0)
11050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
11060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
11080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
11090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (evp != NULL)
11100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		EVP_PKEY_free(evp);
11110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0 && pkey != NULL) {
11120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(pkey);
11130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pkey = NULL;
11140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return pkey;
11170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
11200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_x509sign(src, privkey)
11210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *src, *privkey;
11220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_PKEY *evp;
11240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *bp = (unsigned char *) privkey->v;
11250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sig = NULL;
11260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
11270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pad = RSA_PKCS1_PADDING;
11280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX to be handled EVP_PKEY_DSA */
11300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	evp = d2i_PrivateKey(EVP_PKEY_RSA, NULL, (void *)&bp, privkey->l);
11310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (evp == NULL)
11320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
11330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sig = eay_rsa_sign(src, evp->pkey.rsa);
11350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_PKEY_free(evp);
11370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return sig;
11390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
11420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_get_rsasign(src, rsa)
11430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *src;
11440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RSA *rsa;
11450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_rsa_sign(src, rsa);
11470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
11500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_rsa_sign(vchar_t *src, RSA *rsa)
11510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
11530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sig = NULL;
11540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pad = RSA_PKCS1_PADDING;
11550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = RSA_size(rsa);
11570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sig = vmalloc(len);
11590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sig == NULL)
11600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
11610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = RSA_private_encrypt(src->l, (unsigned char *) src->v,
11630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(unsigned char *) sig->v, rsa, pad);
11640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0 || len != sig->l) {
11660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(sig);
11670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sig = NULL;
11680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return sig;
11710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
11740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_rsa_verify(src, sig, rsa)
11750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *src, *sig;
11760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RSA *rsa;
11770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *xbuf = NULL;
11790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pad = RSA_PKCS1_PADDING;
11800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0;
11810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
11820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = RSA_size(rsa);
11840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xbuf = vmalloc(len);
11850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xbuf == NULL) {
11860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
11870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = RSA_public_decrypt(sig->l, (unsigned char *) sig->v,
11910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(unsigned char *) xbuf->v, rsa, pad);
11920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0 || len != src->l) {
11930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
11940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(xbuf);
11950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = memcmp(src->v, xbuf->v, src->l);
11990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(xbuf);
12000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0)
12010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
12040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
12070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get error string
12080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * MUST load ERR_load_crypto_strings() first.
12090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
12100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *
12110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_strerror()
12120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	static char ebuf[512];
12140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0, n;
12150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned long l;
12160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char buf[200];
12170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const char *file, *data;
12180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int line, flags;
12190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned long es;
12200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1221a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(ANDROID_CHANGES)
1222a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	es = 0;
1223a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#else
12240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	es = CRYPTO_thread_id();
1225a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
12260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0){
12280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		n = snprintf(ebuf + len, sizeof(ebuf) - len,
12290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"%lu:%s:%s:%d:%s ",
12300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				es, ERR_error_string(l, buf), file, line,
12310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(flags & ERR_TXT_STRING) ? data : "");
12320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (n < 0 || n >= sizeof(ebuf) - len)
12330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
12340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len += n;
12350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sizeof(ebuf) < len)
12360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
12370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ebuf;
12400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
12430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangevp_crypt(vchar_t *data, vchar_t *key, vchar_t *iv, const EVP_CIPHER *e, int enc)
12440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
12460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_CIPHER_CTX ctx;
12470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!e)
12490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
12500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (data->l % EVP_CIPHER_block_size(e))
12520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
12530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
12550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
12560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_CIPHER_CTX_init(&ctx);
12580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1259a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if !defined(OPENSSL_IS_BORINGSSL)
12600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch(EVP_CIPHER_nid(e)){
12610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_bf_cbc:
12620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_bf_ecb:
12630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_bf_cfb64:
12640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_bf_ofb64:
12650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_cast5_cbc:
12660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_cast5_ecb:
12670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_cast5_cfb64:
12680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case NID_cast5_ofb64:
12690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX: can we do that also for algos with a fixed key size ?
12700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
12710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* init context without key/iv
12720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang         */
12730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        if (!EVP_CipherInit(&ctx, e, NULL, NULL, enc))
12740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        {
12750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            OpenSSL_BUG();
12760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            vfree(res);
12770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            return NULL;
12780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        }
12790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        /* update key size
12810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang         */
12820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        if (!EVP_CIPHER_CTX_set_key_length(&ctx, key->l))
12830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        {
12840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            OpenSSL_BUG();
12850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            vfree(res);
12860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            return NULL;
12870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        }
12880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        /* finalize context init with desired key size
12900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang         */
12910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        if (!EVP_CipherInit(&ctx, NULL, (u_char *) key->v,
12920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							(u_char *) iv->v, enc))
12930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        {
12940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            OpenSSL_BUG();
12950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            vfree(res);
12960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang            return NULL;
12970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
12990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
1300a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif  /* OPENSSL_IS_BORINGSSL */
13010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!EVP_CipherInit(&ctx, e, (u_char *) key->v,
13020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							(u_char *) iv->v, enc)) {
13030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			OpenSSL_BUG();
13040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(res);
13050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
13060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
1307a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if !defined(OPENSSL_IS_BORINGSSL)
13080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1309a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
13100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* disable openssl padding */
13120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_CIPHER_CTX_set_padding(&ctx, 0);
13130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!EVP_Cipher(&ctx, (u_char *) res->v, (u_char *) data->v, data->l)) {
13150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		OpenSSL_BUG();
13160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
13170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
13180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	EVP_CIPHER_CTX_cleanup(&ctx);
13210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
13230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
13260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangevp_weakkey(vchar_t *key, const EVP_CIPHER *e)
13270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
13290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
13320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangevp_keylen(int len, const EVP_CIPHER *e)
13330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!e)
13350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* EVP functions return lengths in bytes, ipsec-tools
13370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * uses lengths in bits, therefore conversion is required. --AK
13380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
13390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != 0 && len != (EVP_CIPHER_key_length(e) << 3))
13400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return EVP_CIPHER_key_length(e) << 3;
13430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
13460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DES-CBC
13470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
13480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
13490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_des_encrypt(data, key, iv)
13500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
13510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_des_cbc(), 1);
13530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
13560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_des_decrypt(data, key, iv)
13570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
13580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_des_cbc(), 0);
13600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1362a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(OPENSSL_IS_BORINGSSL)
1363a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley/* BoringSSL doesn't implement DES_is_weak_key because the concept is nonsense.
1364a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley * Thankfully, ipsec-tools never actually uses the result of this function. */
1365a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langleystatic int
1366a029281fff6b28b379bd69602f8f5649f0a2740dAdam LangleyDES_is_weak_key(const DES_cblock *key)
1367a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley{
1368a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	return 0;
1369a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley}
1370a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif  /* OPENSSL_IS_BORINGSSL */
1371a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley
13720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
13730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_des_weakkey(key)
13740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
13750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef USE_NEW_DES_API
13770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return DES_is_weak_key((void *)key->v);
13780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
13790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return des_is_weak_key((void *)key->v);
13800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
13840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_des_keylen(len)
13850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
13860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_keylen(len, EVP_des_cbc());
13880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_IDEA_H
13910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
13920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IDEA-CBC
13930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
13940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
13950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_idea_encrypt(data, key, iv)
13960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
13970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
13990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	IDEA_KEY_SCHEDULE ks;
14000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	idea_set_encrypt_key((unsigned char *)key->v, &ks);
14020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for result */
14040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
14050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
14060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* decryption data */
14080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	idea_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
14090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&ks, (unsigned char *)iv->v, IDEA_ENCRYPT);
14100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
14120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
14150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_idea_decrypt(data, key, iv)
14160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
14170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
14190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	IDEA_KEY_SCHEDULE ks, dks;
14200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	idea_set_encrypt_key((unsigned char *)key->v, &ks);
14220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	idea_set_decrypt_key(&ks, &dks);
14230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for result */
14250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
14260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
14270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* decryption data */
14290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	idea_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
14300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&dks, (unsigned char *)iv->v, IDEA_DECRYPT);
14310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
14330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
14360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_idea_weakkey(key)
14370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
14380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;       /* XXX */
14400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
14430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_idea_keylen(len)
14440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
14450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != 0 && len != 128)
14470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
14480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 128;
14490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
14510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
14530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * BLOWFISH-CBC
14540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
14550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
14560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_bf_encrypt(data, key, iv)
14570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
14580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_bf_cbc(), 1);
14600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
14630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_bf_decrypt(data, key, iv)
14640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
14650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_bf_cbc(), 0);
14670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
14700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_bf_weakkey(key)
14710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
14720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;	/* XXX to be done. refer to RFC 2451 */
14740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
14770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_bf_keylen(len)
14780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
14790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0)
14810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 448;
14820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len < 40 || len > 448)
14830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
14840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return len;
14850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_RC5_H
14880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
14890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * RC5-CBC
14900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
14910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
14920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_rc5_encrypt(data, key, iv)
14930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
14940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
14960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RC5_32_KEY ks;
14970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* in RFC 2451, there is information about the number of round. */
14990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RC5_32_set_key(&ks, key->l, (unsigned char *)key->v, 16);
15000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for result */
15020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
15030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
15040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* decryption data */
15060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RC5_32_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
15070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		&ks, (unsigned char *)iv->v, RC5_ENCRYPT);
15080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
15100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
15130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_rc5_decrypt(data, key, iv)
15140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
15150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
15170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RC5_32_KEY ks;
15180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* in RFC 2451, there is information about the number of round. */
15200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RC5_32_set_key(&ks, key->l, (unsigned char *)key->v, 16);
15210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for result */
15230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
15240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
15250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* decryption data */
15270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RC5_32_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
15280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		&ks, (unsigned char *)iv->v, RC5_DECRYPT);
15290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
15310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_rc5_weakkey(key)
15350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
15360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;       /* No known weak keys when used with 16 rounds. */
15380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_rc5_keylen(len)
15430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
15440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0)
15460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 128;
15470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len < 40 || len > 2040)
15480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
15490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return len;
15500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
15520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
15540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3DES-CBC
15550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
15560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
15570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_3des_encrypt(data, key, iv)
15580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
15590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 1);
15610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
15640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_3des_decrypt(data, key, iv)
15650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
15660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 0);
15680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_3des_weakkey(key)
15720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
15730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef USE_NEW_DES_API
15750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return (DES_is_weak_key((void *)key->v) ||
15760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    DES_is_weak_key((void *)(key->v + 8)) ||
15770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    DES_is_weak_key((void *)(key->v + 16)));
15780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
15790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (key->l < 24)
15800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
15810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return (des_is_weak_key((void *)key->v) ||
15830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    des_is_weak_key((void *)(key->v + 8)) ||
15840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    des_is_weak_key((void *)(key->v + 16)));
15850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
15860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_3des_keylen(len)
15900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
15910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != 0 && len != 192)
15930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
15940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 192;
15950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
15980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * CAST-CBC
15990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
16000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
16010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_cast_encrypt(data, key, iv)
16020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
16030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_cast5_cbc(), 1);
16050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
16080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_cast_decrypt(data, key, iv)
16090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
16100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, EVP_cast5_cbc(), 0);
16120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
16150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_cast_weakkey(key)
16160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
16170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;	/* No known weak keys. */
16190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
16220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_cast_keylen(len)
16230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
16240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0)
16260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 128;
16270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len < 40 || len > 128)
16280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
16290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return len;
16300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
16330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * AES(RIJNDAEL)-CBC
16340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
16350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef HAVE_OPENSSL_AES_H
16360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
16370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_aes_encrypt(data, key, iv)
16380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
16390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
16410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	keyInstance k;
16420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	cipherInstance c;
16430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&k, 0, sizeof(k));
16450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rijndael_makeKey(&k, DIR_ENCRYPT, key->l << 3, key->v) < 0)
16460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for result */
16490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
16500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* encryption data */
16530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&c, 0, sizeof(c));
16540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rijndael_cipherInit(&c, MODE_CBC, iv->v) < 0){
16550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
16560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rijndael_blockEncrypt(&c, &k, data->v, data->l << 3, res->v) < 0){
16590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
16600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
16640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
16670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_aes_decrypt(data, key, iv)
16680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data, *key, *iv;
16690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
16710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	keyInstance k;
16720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	cipherInstance c;
16730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&k, 0, sizeof(k));
16750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rijndael_makeKey(&k, DIR_DECRYPT, key->l << 3, key->v) < 0)
16760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for result */
16790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(data->l)) == NULL)
16800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* decryption data */
16830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&c, 0, sizeof(c));
16840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rijndael_cipherInit(&c, MODE_CBC, iv->v) < 0){
16850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
16860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rijndael_blockDecrypt(&c, &k, data->v, data->l << 3, res->v) < 0){
16890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
16900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
16940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
16960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic inline const EVP_CIPHER *
16970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangaes_evp_by_keylen(int keylen)
16980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch(keylen) {
17000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 16:
17010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 128:
17020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return EVP_aes_128_cbc();
1703a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if !defined(ANDROID_CHANGES)
17040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 24:
17050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 192:
17060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return EVP_aes_192_cbc();
1707a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
17080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 32:
17090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 256:
17100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return EVP_aes_256_cbc();
17110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
17120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
17130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
17170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_aes_encrypt(data, key, iv)
17180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang       vchar_t *data, *key, *iv;
17190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 1);
17210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
17240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_aes_decrypt(data, key, iv)
17250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang       vchar_t *data, *key, *iv;
17260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 0);
17280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
17300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_aes_weakkey(key)
17330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
17340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
17360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_aes_keylen(len)
17400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
17410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0)
17430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 128;
17440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != 128 && len != 192 && len != 256)
17450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
17460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return len;
17470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if defined(HAVE_OPENSSL_CAMELLIA_H)
17500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
17510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * CAMELLIA-CBC
17520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
17530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic inline const EVP_CIPHER *
17540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcamellia_evp_by_keylen(int keylen)
17550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch(keylen) {
17570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 16:
17580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 128:
17590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return EVP_camellia_128_cbc();
17600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 24:
17610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 192:
17620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return EVP_camellia_192_cbc();
17630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 32:
17640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case 256:
17650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return EVP_camellia_256_cbc();
17660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
17670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
17680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
17720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_camellia_encrypt(data, key, iv)
17730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang       vchar_t *data, *key, *iv;
17740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, camellia_evp_by_keylen(key->l), 1);
17760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
17790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_camellia_decrypt(data, key, iv)
17800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang       vchar_t *data, *key, *iv;
17810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return evp_crypt(data, key, iv, camellia_evp_by_keylen(key->l), 0);
17830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_camellia_weakkey(key)
17870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
17880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
17900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
17930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_camellia_keylen(len)
17940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
17950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 0)
17970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 128;
17980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != 128 && len != 192 && len != 256)
17990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return len;
18010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
18040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* for ipsec part */
18060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
18070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_null_hashlen()
18080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
18100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
18130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_kpdk_hashlen()
18140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
18160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
18190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_twofish_keylen(len)
18200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
18210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len < 0 || len > 256)
18230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return len;
18250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
18280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_null_keylen(len)
18290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
18300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
18320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HMAC functions
18360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic caddr_t
18380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmac_init(key, md)
18390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
18400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const EVP_MD *md;
18410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_CTX *c = racoon_malloc(sizeof(*c));
18430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Init(c, key->v, key->l, md);
18450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return (caddr_t)c;
18470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef WITH_SHA2
18500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HMAC SHA2-512
18520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
18540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_512_one(key, data)
18550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key, *data;
18560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1857c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
1858c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
1859c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1860c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_hmacsha2_512_init(key);
1861c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_hmacsha2_512_update(ctx, data);
1862c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_hmacsha2_512_final(ctx);
1863c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1864c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
18650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
18680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_512_init(key)
18690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
18700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_hmac_init(key, EVP_sha2_512());
18720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
18750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_512_update(c, data)
18760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
18770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
18780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
18800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
18830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_512_final(c)
18840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
18850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
18870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int l;
18880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0)
18900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
18910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
18930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res->l = l;
18940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_cleanup((HMAC_CTX *)c);
18950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
18960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (SHA512_DIGEST_LENGTH != res->l) {
18980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"hmac sha2_512 length mismatch %zd.\n", res->l);
19000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
19010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
19020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
19050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
19080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HMAC SHA2-384
19090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
19100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
19110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_384_one(key, data)
19120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key, *data;
19130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1914c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
1915c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
1916c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1917c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_hmacsha2_384_init(key);
1918c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_hmacsha2_384_update(ctx, data);
1919c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_hmacsha2_384_final(ctx);
1920c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1921c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
19220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
19250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_384_init(key)
19260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
19270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_hmac_init(key, EVP_sha2_384());
19290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
19320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_384_update(c, data)
19330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
19340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
19350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
19370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
19400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_384_final(c)
19410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
19420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
19440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int l;
19450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0)
19470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
19480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
19500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res->l = l;
19510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_cleanup((HMAC_CTX *)c);
19520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
19530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (SHA384_DIGEST_LENGTH != res->l) {
19550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"hmac sha2_384 length mismatch %zd.\n", res->l);
19570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
19580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
19590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
19620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
19650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HMAC SHA2-256
19660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
19670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
19680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_256_one(key, data)
19690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key, *data;
19700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1971c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
1972c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
1973c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1974c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_hmacsha2_256_init(key);
1975c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_hmacsha2_256_update(ctx, data);
1976c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_hmacsha2_256_final(ctx);
1977c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1978c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
19790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
19820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_256_init(key)
19830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
19840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_hmac_init(key, EVP_sha2_256());
19860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
19890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_256_update(c, data)
19900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
19910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
19920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
19940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
19970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha2_256_final(c)
19980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
19990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
20010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int l;
20020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0)
20040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
20050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
20070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res->l = l;
20080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_cleanup((HMAC_CTX *)c);
20090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
20100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (SHA256_DIGEST_LENGTH != res->l) {
20120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
20130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"hmac sha2_256 length mismatch %zd.\n", res->l);
20140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
20150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
20160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
20190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif	/* WITH_SHA2 */
20210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
20230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HMAC SHA1
20240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
20250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
20260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha1_one(key, data)
20270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key, *data;
20280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2029c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2030c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2031c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2032c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_hmacsha1_init(key);
2033c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_hmacsha1_update(ctx, data);
2034c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_hmacsha1_final(ctx);
2035c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2036c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
20370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
20400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha1_init(key)
20410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
20420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_hmac_init(key, EVP_sha1());
20440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
20470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha1_update(c, data)
20480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
20490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
20500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
20520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
20550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacsha1_final(c)
20560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
20570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
20590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int l;
20600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0)
20620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
20630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
20650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res->l = l;
20660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_cleanup((HMAC_CTX *)c);
20670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
20680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (SHA_DIGEST_LENGTH != res->l) {
20700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
20710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"hmac sha1 length mismatch %zd.\n", res->l);
20720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
20730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
20740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
20770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
20800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HMAC MD5
20810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
20820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
20830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacmd5_one(key, data)
20840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key, *data;
20850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2086c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2087c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2088c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2089c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_hmacmd5_init(key);
2090c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_hmacmd5_update(ctx, data);
2091c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_hmacmd5_final(ctx);
2092c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2093c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
20940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
20970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacmd5_init(key)
20980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *key;
20990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_hmac_init(key, EVP_md5());
21010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
21040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacmd5_update(c, data)
21050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
21060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
21070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
21090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
21120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_hmacmd5_final(c)
21130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
21140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
21160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int l;
21170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0)
21190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
21200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
21220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res->l = l;
21230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	HMAC_cleanup((HMAC_CTX *)c);
21240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
21250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (MD5_DIGEST_LENGTH != res->l) {
21270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
21280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"hmac md5 length mismatch %zd.\n", res->l);
21290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(res);
21300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
21310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
21340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef WITH_SHA2
21370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
21380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SHA2-512 functions
21390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
21400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
21410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_512_init()
21420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA512_CTX *c = racoon_malloc(sizeof(*c));
21440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA512_Init(c);
21460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return((caddr_t)c);
21480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
21510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_512_update(c, data)
21520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
21530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
21540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA512_Update((SHA512_CTX *)c, (unsigned char *) data->v, data->l);
21560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
21580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
21610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_512_final(c)
21620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
21630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
21650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0)
21670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(0);
21680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA512_Final((unsigned char *) res->v, (SHA512_CTX *)c);
21700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
21710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
21730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
21760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_512_one(data)
21770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
21780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2179c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2180c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2181c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2182c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_sha2_512_init();
2183c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_sha2_512_update(ctx, data);
2184c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_sha2_512_final(ctx);
2185c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2186c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
21870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
21900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_512_hashlen()
21910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return SHA512_DIGEST_LENGTH << 3;
21930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
21950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef WITH_SHA2
21970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
21980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SHA2-384 functions
21990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
22000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
22010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_384_init()
22020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA384_CTX *c = racoon_malloc(sizeof(*c));
22040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA384_Init(c);
22060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return((caddr_t)c);
22080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
22110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_384_update(c, data)
22120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
22130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
22140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA384_Update((SHA384_CTX *)c, (unsigned char *) data->v, data->l);
22160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
22180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
22210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_384_final(c)
22220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
22230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
22250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0)
22270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(0);
22280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA384_Final((unsigned char *) res->v, (SHA384_CTX *)c);
22300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
22310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
22330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
22360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_384_one(data)
22370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
22380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2239c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2240c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2241c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2242c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_sha2_384_init();
2243c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_sha2_384_update(ctx, data);
2244c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_sha2_384_final(ctx);
2245c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2246c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
22470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
22500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_384_hashlen()
22510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return SHA384_DIGEST_LENGTH << 3;
22530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
22550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef WITH_SHA2
22570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
22580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SHA2-256 functions
22590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
22600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
22610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_256_init()
22620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA256_CTX *c = racoon_malloc(sizeof(*c));
22640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA256_Init(c);
22660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return((caddr_t)c);
22680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
22710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_256_update(c, data)
22720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
22730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
22740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA256_Update((SHA256_CTX *)c, (unsigned char *) data->v, data->l);
22760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
22780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
22810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_256_final(c)
22820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
22830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
22850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0)
22870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(0);
22880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA256_Final((unsigned char *) res->v, (SHA256_CTX *)c);
22900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
22910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
22930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
22960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_256_one(data)
22970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
22980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2299c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2300c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2301c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2302c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_sha2_256_init();
2303c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_sha2_256_update(ctx, data);
2304c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_sha2_256_final(ctx);
2305c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2306c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
23070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
23100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha2_256_hashlen()
23110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return SHA256_DIGEST_LENGTH << 3;
23130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
23150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
23170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SHA functions
23180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
23190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
23200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha1_init()
23210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA_CTX *c = racoon_malloc(sizeof(*c));
23230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA1_Init(c);
23250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return((caddr_t)c);
23270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
23300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha1_update(c, data)
23310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
23320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
23330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA1_Update((SHA_CTX *)c, data->v, data->l);
23350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
23370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
23400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha1_final(c)
23410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
23420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
23440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0)
23460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(0);
23470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SHA1_Final((unsigned char *) res->v, (SHA_CTX *)c);
23490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
23500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
23520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
23550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha1_one(data)
23560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
23570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2358c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2359c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2360c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2361c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_sha1_init();
2362c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_sha1_update(ctx, data);
2363c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_sha1_final(ctx);
2364c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2365c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
23660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
23690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_sha1_hashlen()
23700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return SHA_DIGEST_LENGTH << 3;
23720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
23750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * MD5 functions
23760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
23770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcaddr_t
23780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_md5_init()
23790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	MD5_CTX *c = racoon_malloc(sizeof(*c));
23810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	MD5_Init(c);
23830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return((caddr_t)c);
23850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
23880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_md5_update(c, data)
23890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
23900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
23910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	MD5_Update((MD5_CTX *)c, data->v, data->l);
23930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
23950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
23980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_md5_final(c)
23990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t c;
24000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res;
24020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0)
24040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(0);
24050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	MD5_Final((unsigned char *) res->v, (MD5_CTX *)c);
24070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)racoon_free(c);
24080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
24100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
24130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_md5_one(data)
24140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *data;
24150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2416c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t ctx;
2417c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *res;
2418c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2419c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	ctx = eay_md5_init();
2420c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	eay_md5_update(ctx, data);
2421c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	res = eay_md5_final(ctx);
2422c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2423c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(res);
24240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
24270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_md5_hashlen()
24280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return MD5_DIGEST_LENGTH << 3;
24300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
24330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * eay_set_random
24340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *   size: number of bytes.
24350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
24360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
24370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_set_random(size)
24380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t size;
24390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *r = NULL;
24410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res = 0;
24420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((r = BN_new()) == NULL)
24440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BN_rand(r, size * 8, 0, 0);
24460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	eay_bn2v(&res, r);
24470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
24490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (r)
24500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		BN_free(r);
24510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(res);
24520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* DH */
24550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
24560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_dh_generate(prime, g, publen, pub, priv)
24570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *prime, **pub, **priv;
24580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int publen;
24590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t g;
24600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *p = NULL;
24620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	DH *dh = NULL;
24630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
24640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* initialize */
24660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* pre-process to generate number */
24670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_v2bn(&p, prime) < 0)
24680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((dh = DH_new()) == NULL)
24710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dh->p = p;
24730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = NULL;	/* p is now part of dh structure */
24740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dh->g = NULL;
24750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((dh->g = BN_new()) == NULL)
24760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!BN_set_word(dh->g, g))
24780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2480a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	if (publen != 0) {
2481a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(OPENSSL_IS_BORINGSSL)
2482a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley		dh->priv_length = publen;
2483a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#else
24840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dh->length = publen;
2485a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
2486a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	}
24870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* generate public and private number */
24890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!DH_generate_key(dh))
24900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* copy results to buffers */
24930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_bn2v(pub, dh->pub_key) < 0)
24940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_bn2v(priv, dh->priv_key) < 0) {
24960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(*pub);
24970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
25010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
25030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (dh != NULL)
25040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		DH_free(dh);
25050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (p != 0)
25060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		BN_free(p);
25070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(error);
25080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
25110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_dh_compute(prime, g, pub, priv, pub2, key)
25120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *prime, *pub, *priv, *pub2, **key;
25130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t g;
25140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
25150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *dh_pub = NULL;
25160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	DH *dh = NULL;
25170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int l;
25180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned char *v = NULL;
25190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
25200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make public number to compute */
25220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_v2bn(&dh_pub, pub2) < 0)
25230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make DH structure */
25260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((dh = DH_new()) == NULL)
25270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_v2bn(&dh->p, prime) < 0)
25290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_v2bn(&dh->pub_key, pub) < 0)
25310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (eay_v2bn(&dh->priv_key, priv) < 0)
25330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2534a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(OPENSSL_IS_BORINGSSL)
2535a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	dh->priv_length = pub2->l * 8;
2536a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#else
25370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dh->length = pub2->l * 8;
2538a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
25390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dh->g = NULL;
25410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((dh->g = BN_new()) == NULL)
25420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!BN_set_word(dh->g, g))
25440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((v = racoon_calloc(prime->l, sizeof(u_char))) == NULL)
25470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((l = DH_compute_key(v, dh_pub, dh)) == -1)
25490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
25500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy((*key)->v + (prime->l - l), v, l);
25510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
25530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
25550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (dh_pub != NULL)
25560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		BN_free(dh_pub);
25570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (dh != NULL)
25580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		DH_free(dh);
25590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (v != NULL)
25600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(v);
25610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(error);
25620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
25650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * convert vchar_t <-> BIGNUM.
25660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
25670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * vchar_t: unit is u_char, network endian, most significant byte first.
25680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * BIGNUM: unit is BN_ULONG, each of BN_ULONG is in host endian,
25690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	least significant BN_ULONG must come first.
25700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
25710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * hex value of "0x3ffe050104" is represented as follows:
25720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	vchar_t: 3f fe 05 01 04
25730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	BIGNUM (BN_ULONG = u_int8_t): 04 01 05 fe 3f
25740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	BIGNUM (BN_ULONG = u_int16_t): 0x0104 0xfe05 0x003f
25750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	BIGNUM (BN_ULONG = u_int32_t_t): 0xfe050104 0x0000003f
25760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
25770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
25780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_v2bn(bn, var)
25790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM **bn;
25800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *var;
25810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
25820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((*bn = BN_bin2bn((unsigned char *) var->v, var->l, NULL)) == NULL)
25830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
25860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
25890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_bn2v(var, bn)
25900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t **var;
25910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *bn;
25920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2593a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(ANDROID_CHANGES)
2594a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	*var = vmalloc(bn->top * sizeof(BN_ULONG));
2595a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#else
25960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*var = vmalloc(bn->top * BN_BYTES);
2597a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
25980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*var == NULL)
25990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(-1);
26000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(*var)->l = BN_bn2bin(bn, (unsigned char *) (*var)->v);
26020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
26040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
26070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_init()
26080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	OpenSSL_add_all_algorithms();
26100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ERR_load_crypto_strings();
26110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_ENGINE_H
26120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ENGINE_load_builtin_engines();
26130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ENGINE_register_all_complete();
26140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
26150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
26180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbase64_decode(char *in, long inlen)
26190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2620a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(OPENSSL_IS_BORINGSSL)
2621a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	vchar_t *res;
2622a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	size_t decoded_size;
2623a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley
2624a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	if (!EVP_DecodedLength(&decoded_size, inlen)) {
2625a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley		return NULL;
2626a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	}
2627a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	res = vmalloc(decoded_size);
2628a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	if (res == NULL) {
2629a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley		return NULL;
2630a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	}
2631a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	if (!EVP_DecodeBase64((uint8_t*) res->v, &res->l, decoded_size, (uint8_t*) in, inlen)) {
2632a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley		vfree(res);
2633a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley		return NULL;
2634a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	}
2635a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	return res;
2636a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#else
26370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO *bio=NULL, *b64=NULL;
26380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res = NULL;
26390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *outb;
26400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	long outlen;
26410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	outb = malloc(inlen * 2);
26430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (outb == NULL)
26440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
26450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bio = BIO_new_mem_buf(in, inlen);
26460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	b64 = BIO_new(BIO_f_base64());
26470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
26480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bio = BIO_push(b64, bio);
26490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	outlen = BIO_read(bio, outb, inlen * 2);
26510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (outlen <= 0) {
26520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
26530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
26540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = vmalloc(outlen);
26570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!res)
26580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
26590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(res->v, outb, outlen);
26610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
26630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (outb)
26640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		free(outb);
26650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bio)
26660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		BIO_free_all(bio);
26670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
2669a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
26700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
26730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbase64_encode(char *in, long inlen)
26740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2675a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(OPENSSL_IS_BORINGSSL)
2676a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	vchar_t *res;
2677a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	size_t encoded_size;
2678a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley
2679a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	if (!EVP_EncodedLength(&encoded_size, inlen)) {
2680a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley		return NULL;
2681a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	}
2682a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	res = vmalloc(encoded_size+1);
2683a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	if (res == NULL) {
2684a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley		return NULL;
2685a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	}
2686a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	EVP_EncodeBlock((uint8_t*) res->v, (uint8_t*) in, inlen);
2687a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	res->v[encoded_size] = 0;
2688a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	return res;
2689a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#else
26900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO *bio=NULL, *b64=NULL;
26910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *ptr;
26920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	long plen = -1;
26930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *res = NULL;
26940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bio = BIO_new(BIO_s_mem());
26960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	b64 = BIO_new(BIO_f_base64());
26970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
26980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bio = BIO_push(b64, bio);
26990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO_write(bio, in, inlen);
27010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIO_flush(bio);
27020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plen = BIO_get_mem_data(bio, &ptr);
27040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = vmalloc(plen+1);
27050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!res)
27060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
27070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy (res->v, ptr, plen);
27090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res->v[plen] = '\0';
27100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
27120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bio)
27130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		BIO_free_all(bio);
27140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
2716a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
27170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic RSA *
27200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbinbuf_pubkey2rsa(vchar_t *binbuf)
27210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *exp, *mod;
27230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RSA *rsa_pub = NULL;
27240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (binbuf->v[0] > binbuf->l - 1) {
27260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: decoded string doesn't make sense.\n");
27270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
27280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	exp = BN_bin2bn((unsigned char *) (binbuf->v + 1), binbuf->v[0], NULL);
27310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	mod = BN_bin2bn((unsigned char *) (binbuf->v + binbuf->v[0] + 1),
27320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			binbuf->l - binbuf->v[0] - 1, NULL);
27330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rsa_pub = RSA_new();
27340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!exp || !mod || !rsa_pub) {
27360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey parsing error: %s\n", eay_strerror());
27370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (exp)
27380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			BN_free(exp);
27390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (mod)
27400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			BN_free(exp);
27410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (rsa_pub)
27420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			RSA_free(rsa_pub);
27430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		rsa_pub = NULL;
27440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
27450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rsa_pub->n = mod;
27480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rsa_pub->e = exp;
27490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
27510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return rsa_pub;
27520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangRSA *
27550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbase64_pubkey2rsa(char *in)
27560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BIGNUM *exp, *mod;
27580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RSA *rsa_pub = NULL;
27590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *binbuf;
27600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (strncmp(in, "0s", 2) != 0) {
27620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: doesn't start with '0s'\n");
27630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
27640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	binbuf = base64_decode(in + 2, strlen(in + 2));
27670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!binbuf) {
27680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: Base64 decoding failed.\n");
27690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
27700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (binbuf->v[0] > binbuf->l - 1) {
27730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: decoded string doesn't make sense.\n");
27740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
27750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rsa_pub = binbuf_pubkey2rsa(binbuf);
27780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
27800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (binbuf)
27810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(binbuf);
27820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return rsa_pub;
27840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangRSA *
27870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbignum_pubkey2rsa(BIGNUM *in)
27880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	RSA *rsa_pub = NULL;
27900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *binbuf;
27910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	binbuf = vmalloc(BN_num_bytes(in));
27930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!binbuf) {
27940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey conversion: memory allocation failed..\n");
27950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
27960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	BN_bn2bin(in, (unsigned char *) binbuf->v);
27990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rsa_pub = binbuf_pubkey2rsa(binbuf);
28010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
28030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (binbuf)
28040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(binbuf);
28050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return rsa_pub;
28070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
28080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangu_int32_t
28100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_random()
28110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
28120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t result;
28130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *vrand;
28140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vrand = eay_set_random(sizeof(result));
28160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&result, vrand->v, sizeof(result));
28170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(vrand);
28180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return result;
28200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
28210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangconst char *
28230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangeay_version()
28240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2825a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(OPENSSL_IS_BORINGSSL)
2826a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	return "(BoringSSL)";
2827a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#else
28280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return SSLeay_version(SSLEAY_VERSION);
2829a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
28300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
2831