aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Langley <agl@google.com>2014-09-30 15:20:01 -0700
committerAdam Langley <agl@google.com>2014-09-30 15:59:52 -0700
commita029281fff6b28b379bd69602f8f5649f0a2740d (patch)
tree8081e33141e5809ee50758735c6d300975df7fa8
parentf4cb1ee4b00abbfb6f968dc25818c23b4b47e584 (diff)
downloadipsec-tools-a029281fff6b28b379bd69602f8f5649f0a2740d.tar.gz
ipsec-tools: update for BoringSSL.
BoringSSL is Google's version of OpenSSL[1] with lots of things cleaned up and removed. This change makes ipsec-tools work with both BoringSSL and Android's existing version of OpenSSL. Some changes are generally applicable but upstream ipsec-tools appears to be dead. I've followed the existing practice of #ifdef'ing the changes but, if there's no upstream, then I'd be happy to be more aggressive about that. Otherwise, apart from a couple of tweaks, the big changes are to the way that the ENGINE works and to replace the PKCS#7 parsing code. [1] https://www.imperialviolet.org/2014/06/20/boringssl.html Change-Id: I32d7eb4e0e0a90f92cf5e8f9675dac4a8edc7a4a
-rw-r--r--Android.mk11
-rw-r--r--main.c20
-rw-r--r--src/racoon/crypto_openssl.c83
-rw-r--r--src/racoon/ipsec_doi.c14
-rw-r--r--src/racoon/isakmp.c5
-rw-r--r--src/racoon/isakmp_cfg.c4
-rw-r--r--src/racoon/isakmp_xauth.c3
-rw-r--r--src/racoon/oakley.c88
8 files changed, 198 insertions, 30 deletions
diff --git a/Android.mk b/Android.mk
index 88ef312..a4f9045 100644
--- a/Android.mk
+++ b/Android.mk
@@ -62,9 +62,14 @@ LOCAL_STATIC_LIBRARIES := libipsec
LOCAL_SHARED_LIBRARIES := libcutils liblog libcrypto
+include $(TOP)/external/openssl/flavor.mk
+ifeq ($(OPENSSL_FLAVOR),BoringSSL)
+ LOCAL_SHARED_LIBRARIES += libkeystore-engine
+endif
+
LOCAL_CFLAGS := -DANDROID_CHANGES -DHAVE_CONFIG_H -DHAVE_OPENSSL_ENGINE_H
-LOCAL_CFLAGS += -Wno-sign-compare -Wno-missing-field-initializers
+LOCAL_CFLAGS += -Wno-sign-compare -Wno-missing-field-initializers -Wno-unused-parameter -Wno-pointer-sign -Werror
LOCAL_MODULE := racoon
@@ -78,9 +83,9 @@ LOCAL_SRC_FILES := \
src/libipsec/pfkey.c \
src/libipsec/ipsec_strerror.c
-LOCAL_CFLAGS := -DHAVE_CONFIG_H -DHAVE_OPENSSL_ENGINE_H
+LOCAL_CFLAGS := -DANDROID_CHANGES -DHAVE_CONFIG_H -DHAVE_OPENSSL_ENGINE_H
-LOCAL_CFLAGS += -Wno-sign-compare -Wno-missing-field-initializers
+LOCAL_CFLAGS += -Wno-sign-compare -Wno-missing-field-initializers -Wno-unused-parameter -Wno-pointer-sign -Werror
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
diff --git a/main.c b/main.c
index e03d89d..a504846 100644
--- a/main.c
+++ b/main.c
@@ -159,17 +159,22 @@ int main(int argc, char **argv)
{
#ifdef ANDROID_CHANGES
int control = android_get_control_and_arguments(&argc, &argv);
- ENGINE *e;
+#if !defined(OPENSSL_IS_BORINGSSL)
+ ENGINE *engine;
+#endif
+
if (control != -1) {
pname = "%p";
monitor_fd(control, NULL);
+#if !defined(OPENSSL_IS_BORINGSSL)
ENGINE_load_dynamic();
- e = ENGINE_by_id("keystore");
- if (!e || !ENGINE_init(e)) {
+ engine = ENGINE_by_id("keystore");
+ if (!engine || !ENGINE_init(engine)) {
do_plog(LLV_ERROR, "ipsec-tools: cannot load keystore engine");
exit(1);
}
+#endif
}
#endif
@@ -207,10 +212,11 @@ int main(int argc, char **argv)
}
}
}
-#ifdef ANDROID_CHANGES
- if (e) {
- ENGINE_finish(e);
- ENGINE_free(e);
+
+#if !defined(OPENSSL_IS_BORINGSSL)
+ if (engine) {
+ ENGINE_finish(engine);
+ ENGINE_free(engine);
}
#endif
return 0;
diff --git a/src/racoon/crypto_openssl.c b/src/racoon/crypto_openssl.c
index 811d0ef..3043f4c 100644
--- a/src/racoon/crypto_openssl.c
+++ b/src/racoon/crypto_openssl.c
@@ -113,6 +113,12 @@ typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
#include "debug.h"
#include "gcmalloc.h"
+#if defined(OPENSSL_IS_BORINGSSL)
+/* HMAC_cleanup is deprecated wrapper in OpenSSL and has been removed in
+ * BoringSSL. */
+#define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx)
+#endif
+
/*
* I hate to cast every parameter to des_xx into void *, but it is
* necessary for SSLeay/OpenSSL portability. It sucks.
@@ -814,7 +820,11 @@ eay_get_x509text(cert)
goto end;
}
+#if defined(ANDROID_CHANGES)
+ len = BIO_get_mem_data(bio, (char**) &bp);
+#else
len = BIO_get_mem_data(bio, &bp);
+#endif
text = racoon_malloc(len + 1);
if (text == NULL)
goto end;
@@ -1208,7 +1218,11 @@ eay_strerror()
int line, flags;
unsigned long es;
+#if defined(ANDROID_CHANGES)
+ es = 0;
+#else
es = CRYPTO_thread_id();
+#endif
while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0){
n = snprintf(ebuf + len, sizeof(ebuf) - len,
@@ -1242,6 +1256,7 @@ evp_crypt(vchar_t *data, vchar_t *key, vchar_t *iv, const EVP_CIPHER *e, int enc
EVP_CIPHER_CTX_init(&ctx);
+#if !defined(OPENSSL_IS_BORINGSSL)
switch(EVP_CIPHER_nid(e)){
case NID_bf_cbc:
case NID_bf_ecb:
@@ -1282,13 +1297,16 @@ evp_crypt(vchar_t *data, vchar_t *key, vchar_t *iv, const EVP_CIPHER *e, int enc
}
break;
default:
+#endif /* OPENSSL_IS_BORINGSSL */
if (!EVP_CipherInit(&ctx, e, (u_char *) key->v,
(u_char *) iv->v, enc)) {
OpenSSL_BUG();
vfree(res);
return NULL;
}
+#if !defined(OPENSSL_IS_BORINGSSL)
}
+#endif
/* disable openssl padding */
EVP_CIPHER_CTX_set_padding(&ctx, 0);
@@ -1341,6 +1359,16 @@ eay_des_decrypt(data, key, iv)
return evp_crypt(data, key, iv, EVP_des_cbc(), 0);
}
+#if defined(OPENSSL_IS_BORINGSSL)
+/* BoringSSL doesn't implement DES_is_weak_key because the concept is nonsense.
+ * Thankfully, ipsec-tools never actually uses the result of this function. */
+static int
+DES_is_weak_key(const DES_cblock *key)
+{
+ return 0;
+}
+#endif /* OPENSSL_IS_BORINGSSL */
+
int
eay_des_weakkey(key)
vchar_t *key;
@@ -1672,9 +1700,11 @@ aes_evp_by_keylen(int keylen)
case 16:
case 128:
return EVP_aes_128_cbc();
+#if !defined(ANDROID_CHANGES)
case 24:
case 192:
return EVP_aes_192_cbc();
+#endif
case 32:
case 256:
return EVP_aes_256_cbc();
@@ -2447,8 +2477,13 @@ eay_dh_generate(prime, g, publen, pub, priv)
if (!BN_set_word(dh->g, g))
goto end;
- if (publen != 0)
+ if (publen != 0) {
+#if defined(OPENSSL_IS_BORINGSSL)
+ dh->priv_length = publen;
+#else
dh->length = publen;
+#endif
+ }
/* generate public and private number */
if (!DH_generate_key(dh))
@@ -2496,7 +2531,11 @@ eay_dh_compute(prime, g, pub, priv, pub2, key)
goto end;
if (eay_v2bn(&dh->priv_key, priv) < 0)
goto end;
+#if defined(OPENSSL_IS_BORINGSSL)
+ dh->priv_length = pub2->l * 8;
+#else
dh->length = pub2->l * 8;
+#endif
dh->g = NULL;
if ((dh->g = BN_new()) == NULL)
@@ -2551,7 +2590,11 @@ eay_bn2v(var, bn)
vchar_t **var;
BIGNUM *bn;
{
+#if defined(ANDROID_CHANGES)
+ *var = vmalloc(bn->top * sizeof(BN_ULONG));
+#else
*var = vmalloc(bn->top * BN_BYTES);
+#endif
if (*var == NULL)
return(-1);
@@ -2574,6 +2617,23 @@ eay_init()
vchar_t *
base64_decode(char *in, long inlen)
{
+#if defined(OPENSSL_IS_BORINGSSL)
+ vchar_t *res;
+ size_t decoded_size;
+
+ if (!EVP_DecodedLength(&decoded_size, inlen)) {
+ return NULL;
+ }
+ res = vmalloc(decoded_size);
+ if (res == NULL) {
+ return NULL;
+ }
+ if (!EVP_DecodeBase64((uint8_t*) res->v, &res->l, decoded_size, (uint8_t*) in, inlen)) {
+ vfree(res);
+ return NULL;
+ }
+ return res;
+#else
BIO *bio=NULL, *b64=NULL;
vchar_t *res = NULL;
char *outb;
@@ -2606,11 +2666,27 @@ out:
BIO_free_all(bio);
return res;
+#endif
}
vchar_t *
base64_encode(char *in, long inlen)
{
+#if defined(OPENSSL_IS_BORINGSSL)
+ vchar_t *res;
+ size_t encoded_size;
+
+ if (!EVP_EncodedLength(&encoded_size, inlen)) {
+ return NULL;
+ }
+ res = vmalloc(encoded_size+1);
+ if (res == NULL) {
+ return NULL;
+ }
+ EVP_EncodeBlock((uint8_t*) res->v, (uint8_t*) in, inlen);
+ res->v[encoded_size] = 0;
+ return res;
+#else
BIO *bio=NULL, *b64=NULL;
char *ptr;
long plen = -1;
@@ -2637,6 +2713,7 @@ out:
BIO_free_all(bio);
return res;
+#endif
}
static RSA *
@@ -2745,5 +2822,9 @@ eay_random()
const char *
eay_version()
{
+#if defined(OPENSSL_IS_BORINGSSL)
+ return "(BoringSSL)";
+#else
return SSLeay_version(SSLEAY_VERSION);
+#endif
}
diff --git a/src/racoon/ipsec_doi.c b/src/racoon/ipsec_doi.c
index 0aa1843..9a59135 100644
--- a/src/racoon/ipsec_doi.c
+++ b/src/racoon/ipsec_doi.c
@@ -1318,7 +1318,11 @@ get_proppair(sa, mode)
"failed to get buffer.\n");
goto bad;
}
+#if defined(ANDROID_CHANGES)
+ memset(pair, 0, MAXPROPPAIRLEN * sizeof(*pair));
+#else
memset(pair, 0, sizeof(pair));
+#endif
bp = (caddr_t)(sab + 1);
tlen = sa->l - sizeof(*sab);
@@ -4008,17 +4012,27 @@ set_identifier_qual(vpp, type, value, qual)
BIO *bio;
unsigned char *ptr = (unsigned char *) new->v, *buf;
size_t len;
+#if defined(ANDROID_CHANGES)
+ char *bio_contents;
+#else
char save;
+#endif
xn = d2i_X509_NAME(NULL, (void *)&ptr, new->l);
bio = BIO_new(BIO_s_mem());
X509_NAME_print_ex(bio, xn, 0, 0);
+#if defined(ANDROID_CHANGES)
+ BIO_write(bio, "\x00", 1);
+ BIO_get_mem_data(bio, &bio_contents);
+ plog(LLV_DEBUG, LOCATION, NULL, "Parsed DN: %s\n", bio_contents);
+#else
len = BIO_get_mem_data(bio, &ptr);
save = ptr[len];
ptr[len] = 0;
plog(LLV_DEBUG, LOCATION, NULL, "Parsed DN: %s\n", ptr);
ptr[len] = save;
+#endif
X509_NAME_free(xn);
BIO_free(bio);
}
diff --git a/src/racoon/isakmp.c b/src/racoon/isakmp.c
index b470b54..7017f21 100644
--- a/src/racoon/isakmp.c
+++ b/src/racoon/isakmp.c
@@ -116,7 +116,7 @@
# ifndef SOL_UDP
# define SOL_UDP 17
# endif
-#ifdef ANDROID_CHANGES
+#if defined(ANDROID_CHANGES) && !defined(__linux)
#define __linux
#endif
# endif /* __linux__ */
@@ -2937,8 +2937,9 @@ log_ph1established(iph1)
isakmp_pindex(&iph1->index, 0));
EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_UP, NULL);
- if(!iph1->rmconf->mode_cfg)
+ if(!iph1->rmconf->mode_cfg) {
EVT_PUSH(iph1->local, iph1->remote, EVTT_NO_ISAKMP_CFG, NULL);
+ }
racoon_free(src);
racoon_free(dst);
diff --git a/src/racoon/isakmp_cfg.c b/src/racoon/isakmp_cfg.c
index a9aa609..fa127dc 100644
--- a/src/racoon/isakmp_cfg.c
+++ b/src/racoon/isakmp_cfg.c
@@ -1841,7 +1841,11 @@ isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
else
l = sizeof(struct in_addr);
memcpy(&tmp, addr, l);
+#if defined(ANDROID_CHANGES)
+ addr = ((uint8_t*) addr) + l;
+#else
addr += l;
+#endif
if((uint32_t)tmp.addr4.s_addr == 0)
break;
diff --git a/src/racoon/isakmp_xauth.c b/src/racoon/isakmp_xauth.c
index a0b799d..3f62587 100644
--- a/src/racoon/isakmp_xauth.c
+++ b/src/racoon/isakmp_xauth.c
@@ -375,6 +375,9 @@ xauth_reply(iph1, port, id, res)
struct ph1handle *iph1;
int port;
int id;
+#if defined(ANDROID_CHANGES)
+ int res;
+#endif
{
struct xauth_state *xst = &iph1->mode_cfg->xauth;
char *usr = xst->authdata.generic.usr;
diff --git a/src/racoon/oakley.c b/src/racoon/oakley.c
index c446bbb..6cdd82a 100644
--- a/src/racoon/oakley.c
+++ b/src/racoon/oakley.c
@@ -38,10 +38,14 @@
#include <sys/socket.h> /* XXX for subjectaltname */
#include <netinet/in.h> /* XXX for subjectaltname */
-#include <openssl/pkcs7.h>
#include <openssl/x509.h>
-#ifdef ANDROID_CHANGES
+#include <openssl/err.h>
+
+#if !defined(OPENSSL_IS_BORINGSSL)
#include <openssl/engine.h>
+#include <openssl/pkcs7.h>
+#else
+#include <openssl/bytestring.h>
#endif
#include <stdlib.h>
@@ -1803,38 +1807,57 @@ end:
#endif
#ifdef ANDROID_CHANGES
+
+#if defined(OPENSSL_IS_BORINGSSL)
+/* EVP_PKEY_from_keystore is from system/security/keystore-engine. */
+extern EVP_PKEY* EVP_PKEY_from_keystore(const char *key_id);
+#endif
+
static vchar_t* keystore_sign(vchar_t* src, const char* path) {
vchar_t* sig = NULL;
+ EVP_PKEY *evp = NULL;
- ENGINE* e = ENGINE_by_id("keystore");
- if (!e) {
+#if !defined(OPENSSL_IS_BORINGSSL)
+ ENGINE *engine = ENGINE_by_id("keystore");
+ if (!engine) {
return NULL;
}
-
- if (!ENGINE_init(e)) {
- ENGINE_free(e);
+ if (!ENGINE_init(engine)) {
+ ENGINE_free(engine);
return NULL;
}
+#endif
const char *key_id;
if (sscanf(path, pname, &key_id) != 1) {
do_plog(LLV_ERROR, "couldn't read private key info\n");
- return NULL;
+ goto out;
}
- EVP_PKEY* evp = ENGINE_load_private_key(e, key_id, NULL, NULL);
+#if !defined(OPENSSL_IS_BORINGSSL)
+ evp = ENGINE_load_private_key(engine, key_id, NULL, NULL);
+#else
+ evp = EVP_PKEY_from_keystore(key_id);
+#endif
if (!evp) {
do_plog(LLV_ERROR, "couldn't retrieve private key");
- ERR_clear_error();
- return NULL;
+ ERR_remove_thread_state(NULL);
+ goto out;
}
- sig = eay_rsa_sign(src, evp->pkey.rsa);
+ if (EVP_PKEY_id(evp) == EVP_PKEY_RSA) {
+ sig = eay_rsa_sign(src, evp->pkey.rsa);
+ }
- EVP_PKEY_free(evp);
+out:
+ if (evp) {
+ EVP_PKEY_free(evp);
+ }
- ENGINE_finish(e);
- ENGINE_free(e);
+#if !defined(OPENSSL_IS_BORINGSSL)
+ ENGINE_finish(engine);
+ ENGINE_free(engine);
+#endif
return sig;
}
@@ -2126,7 +2149,9 @@ oakley_savecert(iph1, gen)
cert_t **c;
u_int8_t type;
STACK_OF(X509) *certs=NULL;
+#if !defined(OPENSSL_IS_BORINGSSL)
PKCS7 *p7;
+#endif
type = *(u_int8_t *)(gen + 1) & 0xff;
@@ -2168,7 +2193,13 @@ oakley_savecert(iph1, gen)
if (type == ISAKMP_CERT_PKCS7) {
u_char *bp;
+#if defined(OPENSSL_IS_BORINGSSL)
+ size_t i;
+ STACK_OF(X509) *certs = sk_X509_new_null();
+ CBS cbs;
+#else
int i;
+#endif
/* Skip the header */
bp = (u_char *)(gen + 1);
@@ -2176,7 +2207,23 @@ oakley_savecert(iph1, gen)
* we know that already
*/
bp++;
- p7 = d2i_PKCS7(NULL, (void *)&bp,
+#if defined(OPENSSL_IS_BORINGSSL)
+ CBS_init(&cbs, bp, ntohs(gen->len) - sizeof(*gen) - 1);
+ if (!PKCS7_get_certificates(certs, &cbs)) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "Failed to parse PKCS#7 CERT.\n");
+ sk_X509_pop_free(certs, X509_free);
+ return -1;
+ }
+
+ if (sk_X509_num(certs) == 0) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "CERT PKCS#7 bundle contains no certs.\n");
+ sk_X509_pop_free(certs, X509_free);
+ return -1;
+ }
+#else
+ p7 = d2i_PKCS7(NULL, (void *)&bp,
ntohs(gen->len) - sizeof(*gen) - 1);
if (!p7) {
@@ -2208,6 +2255,7 @@ oakley_savecert(iph1, gen)
PKCS7_free(p7);
return -1;
}
+#endif
for (i = 0; i < sk_X509_num(certs); i++) {
int len;
@@ -2249,7 +2297,12 @@ oakley_savecert(iph1, gen)
}
break;
}
+
+#if defined(OPENSSL_IS_BORINGSSL)
+ sk_X509_pop_free(certs, X509_free);
+#else
PKCS7_free(p7);
+#endif
} else {
*c = save_certbuf(gen);
@@ -2455,8 +2508,9 @@ oakley_getcr(iph1)
plog(LLV_DEBUG, LOCATION, NULL, "create my CR: %s\n",
s_isakmp_certtype(iph1->rmconf->certtype));
}
- if (buf->l > 1)
+ if (buf->l > 1) {
plogdump(LLV_DEBUG, buf->v, buf->l);
+ }
return buf;
}