Control: tags 828371 + patch
Control: tags 828371 + pending

Dear maintainer,

I've prepared an NMU for lastpass-cli (versioned as 1.0.0-1.1) and
uploaded it to DELAYED/4. Please feel free to tell me if I
should delay it longer.

Regards.
Sebastian
diff -Nru lastpass-cli-1.0.0/debian/changelog lastpass-cli-1.0.0/debian/changelog
--- lastpass-cli-1.0.0/debian/changelog	2016-10-20 16:17:08.000000000 +0200
+++ lastpass-cli-1.0.0/debian/changelog	2016-12-06 21:10:47.000000000 +0100
@@ -1,3 +1,10 @@
+lastpass-cli (1.0.0-1.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * Get it built against openssl 1.1.0 (Closes: #828371).
+
+ -- Sebastian Andrzej Siewior <sebast...@breakpoint.cc>  Tue, 06 Dec 2016 21:10:47 +0100
+
 lastpass-cli (1.0.0-1) unstable; urgency=medium
 
   * New upstream 1.0.0
diff -Nru lastpass-cli-1.0.0/debian/patches/0001-cipher-support-opaque-EVP_CIPHER_CTX.patch lastpass-cli-1.0.0/debian/patches/0001-cipher-support-opaque-EVP_CIPHER_CTX.patch
--- lastpass-cli-1.0.0/debian/patches/0001-cipher-support-opaque-EVP_CIPHER_CTX.patch	1970-01-01 01:00:00.000000000 +0100
+++ lastpass-cli-1.0.0/debian/patches/0001-cipher-support-opaque-EVP_CIPHER_CTX.patch	2016-12-06 21:09:03.000000000 +0100
@@ -0,0 +1,214 @@
+From 6e4ff62df789b55b80c14b2e7b15c25154fbf9fe Mon Sep 17 00:00:00 2001
+From: Bob Copeland <copel...@lastpass.com>
+Date: Mon, 5 Dec 2016 09:55:19 -0500
+Subject: [PATCH 1/3] cipher: support opaque EVP_CIPHER_CTX
+
+In OpenSSL 1.1+, EVP_CIPHER_CTX can no longer be declared on
+the stack; instead you have to declare a pointer and then
+use _new()/_free() to allocate or free it.  These functions
+continue to work on older OpenSSL, so switch to the new
+method.
+
+Signed-off-by: Bob Copeland <copel...@lastpass.com>
+---
+ cipher.c | 36 +++++++++++++++++++++---------------
+ config.c | 33 +++++++++++++++++++--------------
+ 2 files changed, 40 insertions(+), 29 deletions(-)
+
+diff --git a/cipher.c b/cipher.c
+index 71487787af5a..ebae92e0431c 100644
+--- a/cipher.c
++++ b/cipher.c
+@@ -147,36 +147,39 @@ int cipher_rsa_encrypt(const char *plaintext,
+ 
+ char *cipher_aes_decrypt(const unsigned char *ciphertext, size_t len, const unsigned char key[KDF_HASH_LEN])
+ {
+-	EVP_CIPHER_CTX ctx;
++	EVP_CIPHER_CTX *ctx;
+ 	char *plaintext;
+ 	int out_len;
+ 
+ 	if (!len)
+ 		return NULL;
+ 
+-	EVP_CIPHER_CTX_init(&ctx);
++	ctx = EVP_CIPHER_CTX_new();
++	if (!ctx)
++		return NULL;
++
+ 	plaintext = xcalloc(len + AES_BLOCK_SIZE + 1, 1);
+ 	if (len >= 33 && len % 16 == 1 && ciphertext[0] == '!') {
+-		if (!EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, (unsigned char *)(ciphertext + 1)))
++		if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, (unsigned char *)(ciphertext + 1)))
+ 			goto error;
+ 		ciphertext += 17;
+ 		len -= 17;
+ 	} else {
+-		if (!EVP_DecryptInit_ex(&ctx, EVP_aes_256_ecb(), NULL, key, NULL))
++		if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, NULL))
+ 			goto error;
+ 	}
+-	if (!EVP_DecryptUpdate(&ctx, (unsigned char *)plaintext, &out_len, (unsigned char *)ciphertext, len))
++	if (!EVP_DecryptUpdate(ctx, (unsigned char *)plaintext, &out_len, (unsigned char *)ciphertext, len))
+ 		goto error;
+ 	len = out_len;
+-	if (!EVP_DecryptFinal_ex(&ctx, (unsigned char *)(plaintext + out_len), &out_len))
++	if (!EVP_DecryptFinal_ex(ctx, (unsigned char *)(plaintext + out_len), &out_len))
+ 		goto error;
+ 	len += out_len;
+ 	plaintext[len] = '\0';
+-	EVP_CIPHER_CTX_cleanup(&ctx);
++	EVP_CIPHER_CTX_free(ctx);
+ 	return plaintext;
+ 
+ error:
+-	EVP_CIPHER_CTX_cleanup(&ctx);
++	EVP_CIPHER_CTX_free(ctx);
+ 	secure_clear(plaintext, len + AES_BLOCK_SIZE + 1);
+ 	free(plaintext);
+ 	return NULL;
+@@ -188,7 +191,7 @@ size_t cipher_aes_encrypt_bytes(const unsigned char *bytes, size_t len,
+ 				const unsigned char *iv,
+ 				unsigned char **out)
+ {
+-	EVP_CIPHER_CTX ctx;
++	EVP_CIPHER_CTX *ctx;
+ 	int out_len;
+ 	size_t ret_len = 0;
+ 	unsigned char *ctext;
+@@ -197,24 +200,27 @@ size_t cipher_aes_encrypt_bytes(const unsigned char *bytes, size_t len,
+ 	if (!ctext)
+ 		ctext = xcalloc(len + AES_BLOCK_SIZE * 2 + 1, 1);
+ 
+-	EVP_CIPHER_CTX_init(&ctx);
+-	if (!EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv))
++	ctx = EVP_CIPHER_CTX_new();
++	if (!ctx)
+ 		goto error;
+ 
+-	if (!EVP_EncryptUpdate(&ctx, ctext, &out_len, bytes, len))
++	if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
++		goto error;
++
++	if (!EVP_EncryptUpdate(ctx, ctext, &out_len, bytes, len))
+ 		goto error;
+ 
+ 	ret_len += out_len;
+-	if (!EVP_EncryptFinal_ex(&ctx, ctext + ret_len, &out_len))
++	if (!EVP_EncryptFinal_ex(ctx, ctext + ret_len, &out_len))
+ 		goto error;
+ 	ret_len += out_len;
+ 
+-	EVP_CIPHER_CTX_cleanup(&ctx);
++	EVP_CIPHER_CTX_free(ctx);
+ 	*out = ctext;
+ 	return ret_len;
+ 
+ error:
+-	EVP_CIPHER_CTX_cleanup(&ctx);
++	EVP_CIPHER_CTX_free(ctx);
+ 	if (!*out)
+ 		free(ctext);
+ 	die("Failed to encrypt data.");
+diff --git a/config.c b/config.c
+index bd68cfe8b21b..976202c5d6ad 100644
+--- a/config.c
++++ b/config.c
+@@ -319,7 +319,7 @@ size_t config_read_buffer(const char *name, unsigned char **out)
+ 
+ static size_t encrypt_buffer(const char *buffer, size_t in_len, unsigned const char key[KDF_HASH_LEN], char **out)
+ {
+-	EVP_CIPHER_CTX ctx;
++	EVP_CIPHER_CTX *ctx;
+ 	char *ciphertext;
+ 	unsigned char iv[AES_BLOCK_SIZE];
+ 	int out_len;
+@@ -329,31 +329,34 @@ static size_t encrypt_buffer(const char *buffer, size_t in_len, unsigned const c
+ 	if (!RAND_bytes(iv, AES_BLOCK_SIZE))
+ 		die("Could not generate random bytes for CBC IV.");
+ 
+-	EVP_CIPHER_CTX_init(&ctx);
+ 	ciphertext = xcalloc(in_len + AES_BLOCK_SIZE * 2 + SHA256_DIGEST_LENGTH, 1);
+ 
++	ctx = EVP_CIPHER_CTX_new();
++	if (!ctx)
++		goto error;
++
+ 	len = SHA256_DIGEST_LENGTH;
+ 	memcpy(ciphertext + len, iv, AES_BLOCK_SIZE);
+ 	len += AES_BLOCK_SIZE;
+ 
+-	if (!EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv))
++	if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
+ 		goto error;
+-	if (!EVP_EncryptUpdate(&ctx, (unsigned char *)(ciphertext + len), &out_len, (unsigned char *)buffer, in_len))
++	if (!EVP_EncryptUpdate(ctx, (unsigned char *)(ciphertext + len), &out_len, (unsigned char *)buffer, in_len))
+ 		goto error;
+ 	len += out_len;
+-	if (!EVP_EncryptFinal_ex(&ctx, (unsigned char *)(ciphertext + len), &out_len))
++	if (!EVP_EncryptFinal_ex(ctx, (unsigned char *)(ciphertext + len), &out_len))
+ 		goto error;
+ 	len += out_len;
+-	EVP_CIPHER_CTX_cleanup(&ctx);
+ 
+ 	if (!HMAC(EVP_sha256(), key, KDF_HASH_LEN, (unsigned char *)(ciphertext + SHA256_DIGEST_LENGTH), len - SHA256_DIGEST_LENGTH, (unsigned char *)ciphertext, &hmac_len))
+ 		goto error;
+ 
++	EVP_CIPHER_CTX_free(ctx);
+ 	*out = ciphertext;
+ 	return len;
+ 
+ error:
+-	EVP_CIPHER_CTX_cleanup(&ctx);
++	EVP_CIPHER_CTX_free(ctx);
+ 	free(ciphertext);
+ 	die("Failed to encrypt data.");
+ 
+@@ -361,14 +364,16 @@ static size_t encrypt_buffer(const char *buffer, size_t in_len, unsigned const c
+ 
+ static size_t decrypt_buffer(const unsigned char *buffer, size_t in_len, unsigned const char key[KDF_HASH_LEN], unsigned char **out)
+ {
+-	EVP_CIPHER_CTX ctx;
++	EVP_CIPHER_CTX *ctx;
+ 	unsigned char *plaintext = NULL;
+ 	int out_len;
+ 	unsigned int hmac_len;
+ 	size_t len;
+ 	unsigned char hmac[SHA256_DIGEST_LENGTH];
+ 
+-	EVP_CIPHER_CTX_init(&ctx);
++	ctx = EVP_CIPHER_CTX_new();
++	if (!ctx)
++		goto error;
+ 
+ 	if (in_len < (SHA256_DIGEST_LENGTH + AES_BLOCK_SIZE * 2))
+ 		goto error;
+@@ -379,20 +384,20 @@ static size_t decrypt_buffer(const unsigned char *buffer, size_t in_len, unsigne
+ 		goto error;
+ 
+ 	plaintext = xcalloc(in_len + AES_BLOCK_SIZE, 1);
+-	if (!EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, (unsigned char *)(buffer + SHA256_DIGEST_LENGTH)))
++	if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, (unsigned char *)(buffer + SHA256_DIGEST_LENGTH)))
+ 		goto error;
+-	if (!EVP_DecryptUpdate(&ctx, (unsigned char *)plaintext, &out_len, (unsigned char *)(buffer + SHA256_DIGEST_LENGTH + AES_BLOCK_SIZE), in_len - SHA256_DIGEST_LENGTH - AES_BLOCK_SIZE))
++	if (!EVP_DecryptUpdate(ctx, (unsigned char *)plaintext, &out_len, (unsigned char *)(buffer + SHA256_DIGEST_LENGTH + AES_BLOCK_SIZE), in_len - SHA256_DIGEST_LENGTH - AES_BLOCK_SIZE))
+ 		goto error;
+ 	len = out_len;
+-	if (!EVP_DecryptFinal_ex(&ctx, (unsigned char *)(plaintext + out_len), &out_len))
++	if (!EVP_DecryptFinal_ex(ctx, (unsigned char *)(plaintext + out_len), &out_len))
+ 		goto error;
+ 	len += out_len;
+-	EVP_CIPHER_CTX_cleanup(&ctx);
++	EVP_CIPHER_CTX_free(ctx);
+ 	*out = plaintext;
+ 	return len;
+ 
+ error:
+-	EVP_CIPHER_CTX_cleanup(&ctx);
++	EVP_CIPHER_CTX_free(ctx);
+ 	free(plaintext);
+ 	*out = NULL;
+ 	return 0;
+-- 
+2.11.0
+
diff -Nru lastpass-cli-1.0.0/debian/patches/0002-cipher-drop-p8inf-broken-flag-check.patch lastpass-cli-1.0.0/debian/patches/0002-cipher-drop-p8inf-broken-flag-check.patch
--- lastpass-cli-1.0.0/debian/patches/0002-cipher-drop-p8inf-broken-flag-check.patch	1970-01-01 01:00:00.000000000 +0100
+++ lastpass-cli-1.0.0/debian/patches/0002-cipher-drop-p8inf-broken-flag-check.patch	2016-12-06 21:09:03.000000000 +0100
@@ -0,0 +1,37 @@
+From 390c01a8111a4f2fc5b2abb3691c4a0238365922 Mon Sep 17 00:00:00 2001
+From: Bob Copeland <m...@bobcopeland.com>
+Date: Mon, 5 Dec 2016 09:58:07 -0500
+Subject: [PATCH 2/3] cipher: drop p8inf->broken flag check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+struct pkcs8_priv_key_info_st is now opaque as of OpenSSL 1.1
+so we cannot look directly at its flags going forward.
+
+./cipher.c: In function ‘cipher_rsa_decrypt’: ./cipher.c:73:11: error: dereferencing pointer to incomplete type ‘PKCS8_PRIV_KEY_INFO {aka struct
+pkcs8_priv_key_info_st}’
+  if (p8inf->broken)
+           ^
+
+Signed-off-by: Bob Copeland <copel...@lastpass.com>
+---
+ cipher.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/cipher.c b/cipher.c
+index ebae92e0431c..86d19eead546 100644
+--- a/cipher.c
++++ b/cipher.c
+@@ -70,8 +70,6 @@ char *cipher_rsa_decrypt(const unsigned char *ciphertext, size_t len, const stru
+ 	pkey = EVP_PKCS82PKEY(p8inf);
+ 	if (!pkey)
+ 		goto out;
+-	if (p8inf->broken)
+-		goto out;
+ 	rsa = EVP_PKEY_get1_RSA(pkey);
+ 	if (!rsa)
+ 		goto out;
+-- 
+2.11.0
+
diff -Nru lastpass-cli-1.0.0/debian/patches/0003-pbkdf2-support-openssl-1.1.patch lastpass-cli-1.0.0/debian/patches/0003-pbkdf2-support-openssl-1.1.patch
--- lastpass-cli-1.0.0/debian/patches/0003-pbkdf2-support-openssl-1.1.patch	1970-01-01 01:00:00.000000000 +0100
+++ lastpass-cli-1.0.0/debian/patches/0003-pbkdf2-support-openssl-1.1.patch	2016-12-06 21:09:03.000000000 +0100
@@ -0,0 +1,93 @@
+From 0f9e3d940fa2abee3f7dcedceec192e45e471bc6 Mon Sep 17 00:00:00 2001
+From: Bob Copeland <m...@bobcopeland.com>
+Date: Mon, 5 Dec 2016 10:55:49 -0500
+Subject: [PATCH 3/3] pbkdf2: support openssl 1.1+
+
+In OpenSSL 1.1, HMAC_CTX is now opaque and _init/_cleanup functions
+are history.  Change the pbkdf2 implementation to conditionally
+use HMAX_CTX_new()/_free() and use context pointers throughout.
+
+Signed-off-by: Bob Copeland <copel...@lastpass.com>
+---
+ pbkdf2.c | 36 +++++++++++++++++++++++++-----------
+ 1 file changed, 25 insertions(+), 11 deletions(-)
+
+diff --git a/pbkdf2.c b/pbkdf2.c
+index f3c763420bbc..de15bae0d430 100644
+--- a/pbkdf2.c
++++ b/pbkdf2.c
+@@ -1,5 +1,6 @@
+ /*
+  * Copyright (c) 2014-2016 Thomas Hurst.
++ * Copyright (c) 2016 LastPass.
+  *
+  * Permission is hereby granted, free of charge, to any person obtaining a copy
+  * of this software and associated documentation files (the "Software"), to deal
+@@ -40,7 +41,7 @@ int fallback_pkcs5_pbkdf2_hmac(const char *pass, size_t pass_len,
+ 	const unsigned char *salt, size_t salt_len, unsigned int iterations,
+ 	const EVP_MD *digest, size_t key_len, unsigned char *output)
+ {
+-	HMAC_CTX ctx;
++	HMAC_CTX *ctx;
+ 	unsigned char *out = output;
+ 	unsigned int iter = 1, count = 1;
+ 	unsigned int cp_len, i, ret = 0;
+@@ -52,8 +53,17 @@ int fallback_pkcs5_pbkdf2_hmac(const char *pass, size_t pass_len,
+ 
+ 	unsigned char tmp_md[md_len];
+ 
+-	HMAC_CTX_init(&ctx);
+-	ERR_IFZERO(HMAC_Init_ex(&ctx, pass, pass_len, digest, NULL));
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++	HMAC_CTX real_ctx;
++	ctx = &real_ctx;
++	HMAC_CTX_init(ctx);
++#else
++	ctx = HMAC_CTX_new();
++	if (!ctx)
++		return 0;
++#endif
++
++	ERR_IFZERO(HMAC_Init_ex(ctx, pass, pass_len, digest, NULL));
+ 
+ 	while (key_left) {
+ 		cp_len = min(key_left, md_len);
+@@ -64,16 +74,16 @@ int fallback_pkcs5_pbkdf2_hmac(const char *pass, size_t pass_len,
+ 		c[2] = (count >> 8) & 0xff;
+ 		c[3] = (count) & 0xff;
+ 
+-		ERR_IFZERO(HMAC_Init_ex(&ctx, NULL, 0, digest, NULL));
+-		ERR_IFZERO(HMAC_Update(&ctx, salt, salt_len));
+-		ERR_IFZERO(HMAC_Update(&ctx, c, 4));
+-		ERR_IFZERO(HMAC_Final(&ctx, tmp_md, NULL));
++		ERR_IFZERO(HMAC_Init_ex(ctx, NULL, 0, digest, NULL));
++		ERR_IFZERO(HMAC_Update(ctx, salt, salt_len));
++		ERR_IFZERO(HMAC_Update(ctx, c, 4));
++		ERR_IFZERO(HMAC_Final(ctx, tmp_md, NULL));
+ 		memcpy(out, tmp_md, cp_len);
+ 
+ 		for (iter=1; iter < iterations; iter++) {
+-			ERR_IFZERO(HMAC_Init_ex(&ctx, NULL, 0, digest, NULL));
+-			ERR_IFZERO(HMAC_Update(&ctx, tmp_md, md_len));
+-			ERR_IFZERO(HMAC_Final(&ctx, tmp_md, NULL));
++			ERR_IFZERO(HMAC_Init_ex(ctx, NULL, 0, digest, NULL));
++			ERR_IFZERO(HMAC_Update(ctx, tmp_md, md_len));
++			ERR_IFZERO(HMAC_Final(ctx, tmp_md, NULL));
+ 
+ 			for (i = 0; i < cp_len; i++) {
+ 				out[i] ^= tmp_md[i];
+@@ -87,6 +97,10 @@ int fallback_pkcs5_pbkdf2_hmac(const char *pass, size_t pass_len,
+ 	ret = 1;
+ 
+ ERR_LABEL
+-	HMAC_CTX_cleanup(&ctx);
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++	HMAC_CTX_cleanup(ctx);
++#else
++	HMAC_CTX_free(ctx);
++#endif
+ 	return ret;
+ }
+-- 
+2.11.0
+
diff -Nru lastpass-cli-1.0.0/debian/patches/series lastpass-cli-1.0.0/debian/patches/series
--- lastpass-cli-1.0.0/debian/patches/series	2016-10-20 16:16:48.000000000 +0200
+++ lastpass-cli-1.0.0/debian/patches/series	2016-12-06 21:10:47.000000000 +0100
@@ -1 +1,4 @@
 01_build_manpage
+0001-cipher-support-opaque-EVP_CIPHER_CTX.patch
+0002-cipher-drop-p8inf-broken-flag-check.patch
+0003-pbkdf2-support-openssl-1.1.patch

Reply via email to