Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151182246
D17444.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
107 KB
Referenced Files
None
Subscribers
None
D17444.id.diff
View Options
Index: head/crypto/openssh/auth-pam.c
===================================================================
--- head/crypto/openssh/auth-pam.c
+++ head/crypto/openssh/auth-pam.c
@@ -129,6 +129,10 @@
typedef pthread_t sp_pthread_t;
#else
typedef pid_t sp_pthread_t;
+#define pthread_exit fake_pthread_exit
+#define pthread_create fake_pthread_create
+#define pthread_cancel fake_pthread_cancel
+#define pthread_join fake_pthread_join
#endif
struct pam_ctxt {
Index: head/crypto/openssh/auth2.c
===================================================================
--- head/crypto/openssh/auth2.c
+++ head/crypto/openssh/auth2.c
@@ -736,7 +736,7 @@
struct sshkey **tmp, *dup;
int r;
- if ((r = sshkey_demote(key, &dup)) != 0)
+ if ((r = sshkey_from_private(key, &dup)) != 0)
fatal("%s: copy key: %s", __func__, ssh_err(r));
sshkey_free(authctxt->auth_method_key);
authctxt->auth_method_key = dup;
@@ -745,7 +745,7 @@
return;
/* If authenticated, make sure we don't accept this key again */
- if ((r = sshkey_demote(key, &dup)) != 0)
+ if ((r = sshkey_from_private(key, &dup)) != 0)
fatal("%s: copy key: %s", __func__, ssh_err(r));
if (authctxt->nprev_keys >= INT_MAX ||
(tmp = recallocarray(authctxt->prev_keys, authctxt->nprev_keys,
Index: head/crypto/openssh/cipher.h
===================================================================
--- head/crypto/openssh/cipher.h
+++ head/crypto/openssh/cipher.h
@@ -68,8 +68,8 @@
u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *);
-int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int);
-int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *);
+int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, size_t);
+int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *, size_t);
int cipher_get_keyiv_len(const struct sshcipher_ctx *);
#endif /* CIPHER_H */
Index: head/crypto/openssh/cipher.c
===================================================================
--- head/crypto/openssh/cipher.c
+++ head/crypto/openssh/cipher.c
@@ -446,7 +446,7 @@
}
int
-cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
+cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, size_t len)
{
#ifdef WITH_OPENSSL
const struct sshcipher *c = cc->cipher;
@@ -473,7 +473,7 @@
return 0;
else if (evplen < 0)
return SSH_ERR_LIBCRYPTO_ERROR;
- if ((u_int)evplen != len)
+ if ((size_t)evplen != len)
return SSH_ERR_INVALID_ARGUMENT;
#ifndef OPENSSL_HAVE_EVPCTR
if (c->evptype == evp_aes_128_ctr)
@@ -484,14 +484,14 @@
if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
len, iv))
return SSH_ERR_LIBCRYPTO_ERROR;
- } else
- memcpy(iv, cc->evp->iv, len);
+ } else if (!EVP_CIPHER_CTX_get_iv(cc->evp, iv, len))
+ return SSH_ERR_LIBCRYPTO_ERROR;
#endif
return 0;
}
int
-cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
+cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv, size_t len)
{
#ifdef WITH_OPENSSL
const struct sshcipher *c = cc->cipher;
@@ -507,6 +507,8 @@
evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
if (evplen <= 0)
return SSH_ERR_LIBCRYPTO_ERROR;
+ if ((size_t)evplen != len)
+ return SSH_ERR_INVALID_ARGUMENT;
#ifndef OPENSSL_HAVE_EVPCTR
/* XXX iv arg is const, but ssh_aes_ctr_iv isn't */
if (c->evptype == evp_aes_128_ctr)
@@ -518,46 +520,8 @@
if (!EVP_CIPHER_CTX_ctrl(cc->evp,
EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
return SSH_ERR_LIBCRYPTO_ERROR;
- } else
- memcpy(cc->evp->iv, iv, evplen);
+ } else if (!EVP_CIPHER_CTX_set_iv(cc->evp, iv, evplen))
+ return SSH_ERR_LIBCRYPTO_ERROR;
#endif
return 0;
-}
-
-#ifdef WITH_OPENSSL
-#define EVP_X_STATE(evp) (evp)->cipher_data
-#define EVP_X_STATE_LEN(evp) (evp)->cipher->ctx_size
-#endif
-
-int
-cipher_get_keycontext(const struct sshcipher_ctx *cc, u_char *dat)
-{
-#if defined(WITH_OPENSSL) && !defined(OPENSSL_NO_RC4)
- const struct sshcipher *c = cc->cipher;
- int plen = 0;
-
- if (c->evptype == EVP_rc4) {
- plen = EVP_X_STATE_LEN(cc->evp);
- if (dat == NULL)
- return (plen);
- memcpy(dat, EVP_X_STATE(cc->evp), plen);
- }
- return (plen);
-#else
- return 0;
-#endif
-}
-
-void
-cipher_set_keycontext(struct sshcipher_ctx *cc, const u_char *dat)
-{
-#if defined(WITH_OPENSSL) && !defined(OPENSSL_NO_RC4)
- const struct sshcipher *c = cc->cipher;
- int plen;
-
- if (c->evptype == EVP_rc4) {
- plen = EVP_X_STATE_LEN(cc->evp);
- memcpy(EVP_X_STATE(cc->evp), dat, plen);
- }
-#endif
}
Index: head/crypto/openssh/config.h
===================================================================
--- head/crypto/openssh/config.h
+++ head/crypto/openssh/config.h
@@ -394,6 +394,21 @@
/* Define if you have /dev/ptc */
/* #undef HAVE_DEV_PTS_AND_PTC */
+/* Define if libcrypto has DH_get0_key */
+/* #undef HAVE_DH_GET0_KEY */
+
+/* Define if libcrypto has DH_get0_pqg */
+/* #undef HAVE_DH_GET0_PQG */
+
+/* Define if libcrypto has DH_set0_key */
+/* #undef HAVE_DH_SET0_KEY */
+
+/* Define if libcrypto has DH_set0_pqg */
+/* #undef HAVE_DH_SET0_PQG */
+
+/* Define if libcrypto has DH_set_length */
+/* #undef HAVE_DH_SET_LENGTH */
+
/* Define to 1 if you have the <dirent.h> header file. */
#define HAVE_DIRENT_H 1
@@ -406,6 +421,30 @@
/* Define to 1 if you have the `DSA_generate_parameters_ex' function. */
#define HAVE_DSA_GENERATE_PARAMETERS_EX 1
+/* Define if libcrypto has DSA_get0_key */
+/* #undef HAVE_DSA_GET0_KEY */
+
+/* Define if libcrypto has DSA_get0_pqg */
+/* #undef HAVE_DSA_GET0_PQG */
+
+/* Define if libcrypto has DSA_set0_key */
+/* #undef HAVE_DSA_SET0_KEY */
+
+/* Define if libcrypto has DSA_set0_pqg */
+/* #undef HAVE_DSA_SET0_PQG */
+
+/* Define if libcrypto has DSA_SIG_get0 */
+/* #undef HAVE_DSA_SIG_GET0 */
+
+/* Define if libcrypto has DSA_SIG_set0 */
+/* #undef HAVE_DSA_SIG_SET0 */
+
+/* Define if libcrypto has ECDSA_SIG_get0 */
+/* #undef HAVE_ECDSA_SIG_GET0 */
+
+/* Define if libcrypto has ECDSA_SIG_set0 */
+/* #undef HAVE_ECDSA_SIG_SET0 */
+
/* Define to 1 if you have the <elf.h> header file. */
#define HAVE_ELF_H 1
@@ -436,6 +475,15 @@
/* Define if libcrypto has EVP_CIPHER_CTX_ctrl */
#define HAVE_EVP_CIPHER_CTX_CTRL 1
+/* Define if libcrypto has EVP_CIPHER_CTX_set_iv */
+/* #undef HAVE_EVP_CIPHER_CTX_GET_IV */
+
+/* Define if libcrypto has EVP_CIPHER_CTX_iv */
+/* #undef HAVE_EVP_CIPHER_CTX_IV */
+
+/* Define if libcrypto has EVP_CIPHER_CTX_iv_noconst */
+/* #undef HAVE_EVP_CIPHER_CTX_IV_NOCONST */
+
/* Define to 1 if you have the `EVP_DigestFinal_ex' function. */
#define HAVE_EVP_DIGESTFINAL_EX 1
@@ -448,9 +496,18 @@
/* Define to 1 if you have the `EVP_MD_CTX_copy_ex' function. */
#define HAVE_EVP_MD_CTX_COPY_EX 1
+/* Define if libcrypto has EVP_MD_CTX_free */
+/* #undef HAVE_EVP_MD_CTX_FREE */
+
/* Define to 1 if you have the `EVP_MD_CTX_init' function. */
#define HAVE_EVP_MD_CTX_INIT 1
+/* Define if libcrypto has EVP_MD_CTX_new */
+/* #undef HAVE_EVP_MD_CTX_NEW */
+
+/* Define if libcrypto has EVP_PKEY_get0_RSA */
+/* #undef HAVE_EVP_PKEY_GET0_RSA */
+
/* Define to 1 if you have the `EVP_ripemd160' function. */
#define HAVE_EVP_RIPEMD160 1
@@ -973,8 +1030,47 @@
/* Define to 1 if you have the `RSA_generate_key_ex' function. */
#define HAVE_RSA_GENERATE_KEY_EX 1
+/* Define if libcrypto has RSA_get0_crt_params */
+/* #undef HAVE_RSA_GET0_CRT_PARAMS */
+
+/* Define if libcrypto has RSA_get0_factors */
+/* #undef HAVE_RSA_GET0_FACTORS */
+
+/* Define if libcrypto has RSA_get0_key */
+/* #undef HAVE_RSA_GET0_KEY */
+
/* Define to 1 if you have the `RSA_get_default_method' function. */
#define HAVE_RSA_GET_DEFAULT_METHOD 1
+
+/* Define if libcrypto has RSA_meth_dup */
+/* #undef HAVE_RSA_METH_DUP */
+
+/* Define if libcrypto has RSA_meth_free */
+/* #undef HAVE_RSA_METH_FREE */
+
+/* Define if libcrypto has RSA_meth_get_finish */
+/* #undef HAVE_RSA_METH_GET_FINISH */
+
+/* Define if libcrypto has RSA_meth_set1_name */
+/* #undef HAVE_RSA_METH_SET1_NAME */
+
+/* Define if libcrypto has RSA_meth_set_finish */
+/* #undef HAVE_RSA_METH_SET_FINISH */
+
+/* Define if libcrypto has RSA_meth_set_priv_dec */
+/* #undef HAVE_RSA_METH_SET_PRIV_DEC */
+
+/* Define if libcrypto has RSA_meth_set_priv_enc */
+/* #undef HAVE_RSA_METH_SET_PRIV_ENC */
+
+/* Define if libcrypto has RSA_get0_srt_params */
+/* #undef HAVE_RSA_SET0_CRT_PARAMS */
+
+/* Define if libcrypto has RSA_set0_factors */
+/* #undef HAVE_RSA_SET0_FACTORS */
+
+/* Define if libcrypto has RSA_set0_key */
+/* #undef HAVE_RSA_SET0_KEY */
/* Define to 1 if you have the <sandbox.h> header file. */
/* #undef HAVE_SANDBOX_H */
Index: head/crypto/openssh/configure.ac
===================================================================
--- head/crypto/openssh/configure.ac
+++ head/crypto/openssh/configure.ac
@@ -2657,9 +2657,10 @@
AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")])
;;
100*) ;; # 1.0.x
+ 101*) ;; # 1.1.x
200*) ;; # LibreSSL
*)
- AC_MSG_ERROR([OpenSSL >= 1.1.0 is not yet supported (have "$ssl_library_ver")])
+ AC_MSG_ERROR([OpenSSL > 1.1.x is not yet supported (have "$ssl_library_ver")])
;;
esac
AC_MSG_RESULT([$ssl_library_ver])
@@ -2831,6 +2832,115 @@
AC_SEARCH_LIBS([EVP_CIPHER_CTX_ctrl], [crypto],
[AC_DEFINE([HAVE_EVP_CIPHER_CTX_CTRL], [1],
[Define if libcrypto has EVP_CIPHER_CTX_ctrl])])
+
+ # LibreSSL/OpenSSL 1.1x API
+ AC_SEARCH_LIBS([DH_get0_key], [crypto],
+ [AC_DEFINE([HAVE_DH_GET0_KEY], [1],
+ [Define if libcrypto has DH_get0_key])])
+ AC_SEARCH_LIBS([DH_get0_pqg], [crypto],
+ [AC_DEFINE([HAVE_DH_GET0_PQG], [1],
+ [Define if libcrypto has DH_get0_pqg])])
+ AC_SEARCH_LIBS([DH_set0_key], [crypto],
+ [AC_DEFINE([HAVE_DH_SET0_KEY], [1],
+ [Define if libcrypto has DH_set0_key])])
+ AC_SEARCH_LIBS([DH_set_length], [crypto],
+ [AC_DEFINE([HAVE_DH_SET_LENGTH], [1],
+ [Define if libcrypto has DH_set_length])])
+ AC_SEARCH_LIBS([DH_set0_pqg], [crypto],
+ [AC_DEFINE([HAVE_DH_SET0_PQG], [1],
+ [Define if libcrypto has DH_set0_pqg])])
+
+ AC_SEARCH_LIBS([DSA_get0_key], [crypto],
+ [AC_DEFINE([HAVE_DSA_GET0_KEY], [1],
+ [Define if libcrypto has DSA_get0_key])])
+ AC_SEARCH_LIBS([DSA_get0_pqg], [crypto],
+ [AC_DEFINE([HAVE_DSA_GET0_PQG], [1],
+ [Define if libcrypto has DSA_get0_pqg])])
+ AC_SEARCH_LIBS([DSA_set0_key], [crypto],
+ [AC_DEFINE([HAVE_DSA_SET0_KEY], [1],
+ [Define if libcrypto has DSA_set0_key])])
+ AC_SEARCH_LIBS([DSA_set0_pqg], [crypto],
+ [AC_DEFINE([HAVE_DSA_SET0_PQG], [1],
+ [Define if libcrypto has DSA_set0_pqg])])
+
+ AC_SEARCH_LIBS([DSA_SIG_get0], [crypto],
+ [AC_DEFINE([HAVE_DSA_SIG_GET0], [1],
+ [Define if libcrypto has DSA_SIG_get0])])
+ AC_SEARCH_LIBS([DSA_SIG_set0], [crypto],
+ [AC_DEFINE([HAVE_DSA_SIG_SET0], [1],
+ [Define if libcrypto has DSA_SIG_set0])])
+
+ AC_SEARCH_LIBS([ECDSA_SIG_get0], [crypto],
+ [AC_DEFINE([HAVE_ECDSA_SIG_GET0], [1],
+ [Define if libcrypto has ECDSA_SIG_get0])])
+ AC_SEARCH_LIBS([ECDSA_SIG_set0], [crypto],
+ [AC_DEFINE([HAVE_ECDSA_SIG_SET0], [1],
+ [Define if libcrypto has ECDSA_SIG_set0])])
+
+ AC_SEARCH_LIBS([EVP_CIPHER_CTX_iv], [crypto],
+ [AC_DEFINE([HAVE_EVP_CIPHER_CTX_IV], [1],
+ [Define if libcrypto has EVP_CIPHER_CTX_iv])])
+ AC_SEARCH_LIBS([EVP_CIPHER_CTX_iv_noconst], [crypto],
+ [AC_DEFINE([HAVE_EVP_CIPHER_CTX_IV_NOCONST], [1],
+ [Define if libcrypto has EVP_CIPHER_CTX_iv_noconst])])
+ AC_SEARCH_LIBS([EVP_CIPHER_CTX_get_iv], [crypto],
+ [AC_DEFINE([HAVE_EVP_CIPHER_CTX_GET_IV], [1],
+ [Define if libcrypto has EVP_CIPHER_CTX_get_iv])])
+ AC_SEARCH_LIBS([EVP_CIPHER_CTX_set_iv], [crypto],
+ [AC_DEFINE([HAVE_EVP_CIPHER_CTX_GET_IV], [1],
+ [Define if libcrypto has EVP_CIPHER_CTX_set_iv])])
+
+ AC_SEARCH_LIBS([RSA_get0_crt_params], [crypto],
+ [AC_DEFINE([HAVE_RSA_GET0_CRT_PARAMS], [1],
+ [Define if libcrypto has RSA_get0_crt_params])])
+ AC_SEARCH_LIBS([RSA_get0_factors], [crypto],
+ [AC_DEFINE([HAVE_RSA_GET0_FACTORS], [1],
+ [Define if libcrypto has RSA_get0_factors])])
+ AC_SEARCH_LIBS([RSA_get0_key], [crypto],
+ [AC_DEFINE([HAVE_RSA_GET0_KEY], [1],
+ [Define if libcrypto has RSA_get0_key])])
+ AC_SEARCH_LIBS([RSA_set0_crt_params], [crypto],
+ [AC_DEFINE([HAVE_RSA_SET0_CRT_PARAMS], [1],
+ [Define if libcrypto has RSA_get0_srt_params])])
+ AC_SEARCH_LIBS([RSA_set0_factors], [crypto],
+ [AC_DEFINE([HAVE_RSA_SET0_FACTORS], [1],
+ [Define if libcrypto has RSA_set0_factors])])
+ AC_SEARCH_LIBS([RSA_set0_key], [crypto],
+ [AC_DEFINE([HAVE_RSA_SET0_KEY], [1],
+ [Define if libcrypto has RSA_set0_key])])
+
+ AC_SEARCH_LIBS([RSA_meth_free], [crypto],
+ [AC_DEFINE([HAVE_RSA_METH_FREE], [1],
+ [Define if libcrypto has RSA_meth_free])])
+ AC_SEARCH_LIBS([RSA_meth_dup], [crypto],
+ [AC_DEFINE([HAVE_RSA_METH_DUP], [1],
+ [Define if libcrypto has RSA_meth_dup])])
+ AC_SEARCH_LIBS([RSA_meth_set1_name], [crypto],
+ [AC_DEFINE([HAVE_RSA_METH_SET1_NAME], [1],
+ [Define if libcrypto has RSA_meth_set1_name])])
+ AC_SEARCH_LIBS([RSA_meth_get_finish], [crypto],
+ [AC_DEFINE([HAVE_RSA_METH_GET_FINISH], [1],
+ [Define if libcrypto has RSA_meth_get_finish])])
+ AC_SEARCH_LIBS([RSA_meth_set_priv_enc], [crypto],
+ [AC_DEFINE([HAVE_RSA_METH_SET_PRIV_ENC], [1],
+ [Define if libcrypto has RSA_meth_set_priv_enc])])
+ AC_SEARCH_LIBS([RSA_meth_set_priv_dec], [crypto],
+ [AC_DEFINE([HAVE_RSA_METH_SET_PRIV_DEC], [1],
+ [Define if libcrypto has RSA_meth_set_priv_dec])])
+ AC_SEARCH_LIBS([RSA_meth_set_finish], [crypto],
+ [AC_DEFINE([HAVE_RSA_METH_SET_FINISH], [1],
+ [Define if libcrypto has RSA_meth_set_finish])])
+
+ AC_SEARCH_LIBS([EVP_PKEY_get0_RSA], [crypto],
+ [AC_DEFINE([HAVE_EVP_PKEY_GET0_RSA], [1],
+ [Define if libcrypto has EVP_PKEY_get0_RSA])])
+
+ AC_SEARCH_LIBS([EVP_MD_CTX_new], [crypto],
+ [AC_DEFINE([HAVE_EVP_MD_CTX_NEW], [1],
+ [Define if libcrypto has EVP_MD_CTX_new])])
+ AC_SEARCH_LIBS([EVP_MD_CTX_free], [crypto],
+ [AC_DEFINE([HAVE_EVP_MD_CTX_FREE], [1],
+ [Define if libcrypto has EVP_MD_CTX_free])])
AC_MSG_CHECKING([if EVP_DigestUpdate returns an int])
AC_LINK_IFELSE(
Index: head/crypto/openssh/dh.h
===================================================================
--- head/crypto/openssh/dh.h
+++ head/crypto/openssh/dh.h
@@ -42,7 +42,7 @@
DH *dh_new_group_fallback(int);
int dh_gen_key(DH *, int);
-int dh_pub_is_valid(DH *, BIGNUM *);
+int dh_pub_is_valid(const DH *, const BIGNUM *);
u_int dh_estimate(int);
Index: head/crypto/openssh/dh.c
===================================================================
--- head/crypto/openssh/dh.c
+++ head/crypto/openssh/dh.c
@@ -43,6 +43,8 @@
#include "misc.h"
#include "ssherr.h"
+#include "openbsd-compat/openssl-compat.h"
+
static int
parse_prime(int linenum, char *line, struct dhgroup *dhg)
{
@@ -216,14 +218,17 @@
/* diffie-hellman-groupN-sha1 */
int
-dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
+dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
{
int i;
int n = BN_num_bits(dh_pub);
int bits_set = 0;
BIGNUM *tmp;
+ const BIGNUM *dh_p;
- if (dh_pub->neg) {
+ DH_get0_pqg(dh, &dh_p, NULL, NULL);
+
+ if (BN_is_negative(dh_pub)) {
logit("invalid public DH value: negative");
return 0;
}
@@ -236,7 +241,7 @@
error("%s: BN_new failed", __func__);
return 0;
}
- if (!BN_sub(tmp, dh->p, BN_value_one()) ||
+ if (!BN_sub(tmp, dh_p, BN_value_one()) ||
BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
BN_clear_free(tmp);
logit("invalid public DH value: >= p-1");
@@ -247,14 +252,14 @@
for (i = 0; i <= n; i++)
if (BN_is_bit_set(dh_pub, i))
bits_set++;
- debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
+ debug2("bits set: %d/%d", bits_set, BN_num_bits(dh_p));
/*
* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
*/
if (bits_set < 4) {
logit("invalid public DH value (%d/%d)",
- bits_set, BN_num_bits(dh->p));
+ bits_set, BN_num_bits(dh_p));
return 0;
}
return 1;
@@ -264,9 +269,12 @@
dh_gen_key(DH *dh, int need)
{
int pbits;
+ const BIGNUM *dh_p, *pub_key;
- if (need < 0 || dh->p == NULL ||
- (pbits = BN_num_bits(dh->p)) <= 0 ||
+ DH_get0_pqg(dh, &dh_p, NULL, NULL);
+
+ if (need < 0 || dh_p == NULL ||
+ (pbits = BN_num_bits(dh_p)) <= 0 ||
need > INT_MAX / 2 || 2 * need > pbits)
return SSH_ERR_INVALID_ARGUMENT;
if (need < 256)
@@ -275,13 +283,14 @@
* Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
* so double requested need here.
*/
- dh->length = MINIMUM(need * 2, pbits - 1);
- if (DH_generate_key(dh) == 0 ||
- !dh_pub_is_valid(dh, dh->pub_key)) {
- BN_clear_free(dh->priv_key);
- dh->priv_key = NULL;
+ if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
return SSH_ERR_LIBCRYPTO_ERROR;
- }
+
+ if (DH_generate_key(dh) == 0)
+ return SSH_ERR_LIBCRYPTO_ERROR;
+ DH_get0_key(dh, &pub_key, NULL);
+ if (!dh_pub_is_valid(dh, pub_key))
+ return SSH_ERR_INVALID_FORMAT;
return 0;
}
@@ -289,22 +298,27 @@
dh_new_group_asc(const char *gen, const char *modulus)
{
DH *dh;
+ BIGNUM *dh_p = NULL, *dh_g = NULL;
if ((dh = DH_new()) == NULL)
return NULL;
- if (BN_hex2bn(&dh->p, modulus) == 0 ||
- BN_hex2bn(&dh->g, gen) == 0) {
- DH_free(dh);
- return NULL;
- }
- return (dh);
+ if (BN_hex2bn(&dh_p, modulus) == 0 ||
+ BN_hex2bn(&dh_g, gen) == 0)
+ goto fail;
+ if (!DH_set0_pqg(dh, dh_p, NULL, dh_g))
+ goto fail;
+ return dh;
+ fail:
+ DH_free(dh);
+ BN_clear_free(dh_p);
+ BN_clear_free(dh_g);
+ return NULL;
}
/*
* This just returns the group, we still need to generate the exchange
* value.
*/
-
DH *
dh_new_group(BIGNUM *gen, BIGNUM *modulus)
{
@@ -312,10 +326,12 @@
if ((dh = DH_new()) == NULL)
return NULL;
- dh->p = modulus;
- dh->g = gen;
+ if (!DH_set0_pqg(dh, modulus, NULL, gen)) {
+ DH_free(dh);
+ return NULL;
+ }
- return (dh);
+ return dh;
}
/* rfc2409 "Second Oakley Group" (1024 bits) */
Index: head/crypto/openssh/digest-openssl.c
===================================================================
--- head/crypto/openssh/digest-openssl.c
+++ head/crypto/openssh/digest-openssl.c
@@ -43,7 +43,7 @@
struct ssh_digest_ctx {
int alg;
- EVP_MD_CTX mdctx;
+ EVP_MD_CTX *mdctx;
};
struct ssh_digest {
@@ -106,7 +106,7 @@
size_t
ssh_digest_blocksize(struct ssh_digest_ctx *ctx)
{
- return EVP_MD_CTX_block_size(&ctx->mdctx);
+ return EVP_MD_CTX_block_size(ctx->mdctx);
}
struct ssh_digest_ctx *
@@ -118,11 +118,14 @@
if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL))
return NULL;
ret->alg = alg;
- EVP_MD_CTX_init(&ret->mdctx);
- if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) {
+ if ((ret->mdctx = EVP_MD_CTX_new()) == NULL) {
free(ret);
return NULL;
}
+ if (EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) {
+ ssh_digest_free(ret);
+ return NULL;
+ }
return ret;
}
@@ -132,7 +135,7 @@
if (from->alg != to->alg)
return SSH_ERR_INVALID_ARGUMENT;
/* we have bcopy-style order while openssl has memcpy-style */
- if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx))
+ if (!EVP_MD_CTX_copy_ex(to->mdctx, from->mdctx))
return SSH_ERR_LIBCRYPTO_ERROR;
return 0;
}
@@ -140,7 +143,7 @@
int
ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
{
- if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
+ if (EVP_DigestUpdate(ctx->mdctx, m, mlen) != 1)
return SSH_ERR_LIBCRYPTO_ERROR;
return 0;
}
@@ -161,7 +164,7 @@
return SSH_ERR_INVALID_ARGUMENT;
if (dlen < digest->digest_len) /* No truncation allowed */
return SSH_ERR_INVALID_ARGUMENT;
- if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1)
+ if (EVP_DigestFinal_ex(ctx->mdctx, d, &l) != 1)
return SSH_ERR_LIBCRYPTO_ERROR;
if (l != digest->digest_len) /* sanity */
return SSH_ERR_INTERNAL_ERROR;
@@ -171,11 +174,10 @@
void
ssh_digest_free(struct ssh_digest_ctx *ctx)
{
- if (ctx != NULL) {
- EVP_MD_CTX_cleanup(&ctx->mdctx);
- explicit_bzero(ctx, sizeof(*ctx));
- free(ctx);
- }
+ if (ctx == NULL)
+ return;
+ EVP_MD_CTX_free(ctx->mdctx);
+ freezero(ctx, sizeof(*ctx));
}
int
Index: head/crypto/openssh/kexdh.c
===================================================================
--- head/crypto/openssh/kexdh.c
+++ head/crypto/openssh/kexdh.c
@@ -33,6 +33,8 @@
#include <openssl/evp.h>
+#include "openbsd-compat/openssl-compat.h"
+
#include "ssh2.h"
#include "sshkey.h"
#include "cipher.h"
Index: head/crypto/openssh/kexdhc.c
===================================================================
--- head/crypto/openssh/kexdhc.c
+++ head/crypto/openssh/kexdhc.c
@@ -36,6 +36,8 @@
#include <string.h>
#include <signal.h>
+#include "openbsd-compat/openssl-compat.h"
+
#include "sshkey.h"
#include "cipher.h"
#include "digest.h"
@@ -56,6 +58,7 @@
{
struct kex *kex = ssh->kex;
int r;
+ const BIGNUM *pub_key;
/* generate and send 'e', client DH public key */
switch (kex->kex_type) {
@@ -81,15 +84,17 @@
goto out;
}
debug("sending SSH2_MSG_KEXDH_INIT");
- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
- (r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||
+ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
+ goto out;
+ DH_get0_key(kex->dh, &pub_key, NULL);
+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, kex->dh);
fprintf(stderr, "pub= ");
- BN_print_fp(stderr, kex->dh->pub_key);
+ BN_print_fp(stderr, pub_key);
fprintf(stderr, "\n");
#endif
debug("expecting SSH2_MSG_KEXDH_REPLY");
@@ -104,6 +109,7 @@
{
struct kex *kex = ssh->kex;
BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
+ const BIGNUM *pub_key;
struct sshkey *server_host_key = NULL;
u_char *kbuf = NULL, *server_host_key_blob = NULL, *signature = NULL;
u_char hash[SSH_DIGEST_MAX_LENGTH];
@@ -168,6 +174,7 @@
#endif
/* calc and verify H */
+ DH_get0_key(kex->dh, &pub_key, NULL);
hashlen = sizeof(hash);
if ((r = kex_dh_hash(
kex->hash_alg,
@@ -176,7 +183,7 @@
sshbuf_ptr(kex->my), sshbuf_len(kex->my),
sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
server_host_key_blob, sbloblen,
- kex->dh->pub_key,
+ pub_key,
dh_server_pub,
shared_secret,
hash, &hashlen)) != 0)
Index: head/crypto/openssh/kexdhs.c
===================================================================
--- head/crypto/openssh/kexdhs.c
+++ head/crypto/openssh/kexdhs.c
@@ -35,6 +35,8 @@
#include <openssl/dh.h>
+#include "openbsd-compat/openssl-compat.h"
+
#include "sshkey.h"
#include "cipher.h"
#include "digest.h"
@@ -95,6 +97,7 @@
{
struct kex *kex = ssh->kex;
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
+ const BIGNUM *pub_key;
struct sshkey *server_host_public, *server_host_private;
u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
u_char hash[SSH_DIGEST_MAX_LENGTH];
@@ -121,6 +124,7 @@
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
+ DH_get0_key(kex->dh, &pub_key, NULL);
if ((r = sshpkt_get_bignum2(ssh, dh_client_pub)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
goto out;
@@ -130,12 +134,9 @@
BN_print_fp(stderr, dh_client_pub);
fprintf(stderr, "\n");
debug("bits %d", BN_num_bits(dh_client_pub));
-#endif
-
-#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, kex->dh);
fprintf(stderr, "pub= ");
- BN_print_fp(stderr, kex->dh->pub_key);
+ BN_print_fp(stderr, pub_key);
fprintf(stderr, "\n");
#endif
if (!dh_pub_is_valid(kex->dh, dh_client_pub)) {
@@ -171,7 +172,7 @@
sshbuf_ptr(kex->my), sshbuf_len(kex->my),
server_host_key_blob, sbloblen,
dh_client_pub,
- kex->dh->pub_key,
+ pub_key,
shared_secret,
hash, &hashlen)) != 0)
goto out;
@@ -197,7 +198,7 @@
/* send server hostkey, DH pubkey 'f' and signed H */
if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 ||
(r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */
+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */
(r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
Index: head/crypto/openssh/kexgex.c
===================================================================
--- head/crypto/openssh/kexgex.c
+++ head/crypto/openssh/kexgex.c
@@ -33,6 +33,8 @@
#include <openssl/evp.h>
#include <signal.h>
+#include "openbsd-compat/openssl-compat.h"
+
#include "sshkey.h"
#include "cipher.h"
#include "kex.h"
Index: head/crypto/openssh/kexgexc.c
===================================================================
--- head/crypto/openssh/kexgexc.c
+++ head/crypto/openssh/kexgexc.c
@@ -37,6 +37,8 @@
#include <string.h>
#include <signal.h>
+#include "openbsd-compat/openssl-compat.h"
+
#include "sshkey.h"
#include "cipher.h"
#include "digest.h"
@@ -93,6 +95,7 @@
{
struct kex *kex = ssh->kex;
BIGNUM *p = NULL, *g = NULL;
+ const BIGNUM *pub_key;
int r, bits;
debug("got SSH2_MSG_KEX_DH_GEX_GROUP");
@@ -118,16 +121,18 @@
p = g = NULL; /* belong to kex->dh now */
/* generate and send 'e', client DH public key */
- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
- (r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||
+ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
+ goto out;
+ DH_get0_key(kex->dh, &pub_key, NULL);
+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
debug("SSH2_MSG_KEX_DH_GEX_INIT sent");
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, kex->dh);
fprintf(stderr, "pub= ");
- BN_print_fp(stderr, kex->dh->pub_key);
+ BN_print_fp(stderr, pub_key);
fprintf(stderr, "\n");
#endif
ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL);
@@ -144,6 +149,7 @@
{
struct kex *kex = ssh->kex;
BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
+ const BIGNUM *pub_key, *dh_p, *dh_g;
struct sshkey *server_host_key = NULL;
u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
u_char hash[SSH_DIGEST_MAX_LENGTH];
@@ -211,6 +217,8 @@
kex->min = kex->max = -1;
/* calc and verify H */
+ DH_get0_key(kex->dh, &pub_key, NULL);
+ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g);
hashlen = sizeof(hash);
if ((r = kexgex_hash(
kex->hash_alg,
@@ -220,8 +228,8 @@
sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
server_host_key_blob, sbloblen,
kex->min, kex->nbits, kex->max,
- kex->dh->p, kex->dh->g,
- kex->dh->pub_key,
+ dh_p, dh_g,
+ pub_key,
dh_server_pub,
shared_secret,
hash, &hashlen)) != 0)
Index: head/crypto/openssh/kexgexs.c
===================================================================
--- head/crypto/openssh/kexgexs.c
+++ head/crypto/openssh/kexgexs.c
@@ -36,6 +36,8 @@
#include <openssl/dh.h>
+#include "openbsd-compat/openssl-compat.h"
+
#include "sshkey.h"
#include "cipher.h"
#include "digest.h"
@@ -72,6 +74,7 @@
struct kex *kex = ssh->kex;
int r;
u_int min = 0, max = 0, nbits = 0;
+ const BIGNUM *dh_p, *dh_g;
debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
if ((r = sshpkt_get_u32(ssh, &min)) != 0 ||
@@ -101,9 +104,10 @@
goto out;
}
debug("SSH2_MSG_KEX_DH_GEX_GROUP sent");
+ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g);
if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 ||
- (r = sshpkt_put_bignum2(ssh, kex->dh->p)) != 0 ||
- (r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 ||
+ (r = sshpkt_put_bignum2(ssh, dh_p)) != 0 ||
+ (r = sshpkt_put_bignum2(ssh, dh_g)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
@@ -123,6 +127,7 @@
{
struct kex *kex = ssh->kex;
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
+ const BIGNUM *pub_key, *dh_p, *dh_g;
struct sshkey *server_host_public, *server_host_private;
u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
u_char hash[SSH_DIGEST_MAX_LENGTH];
@@ -153,17 +158,17 @@
(r = sshpkt_get_end(ssh)) != 0)
goto out;
+ DH_get0_key(kex->dh, &pub_key, NULL);
+ DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g);
+
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_client_pub= ");
BN_print_fp(stderr, dh_client_pub);
fprintf(stderr, "\n");
debug("bits %d", BN_num_bits(dh_client_pub));
-#endif
-
-#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, kex->dh);
fprintf(stderr, "pub= ");
- BN_print_fp(stderr, kex->dh->pub_key);
+ BN_print_fp(stderr, pub_key);
fprintf(stderr, "\n");
#endif
if (!dh_pub_is_valid(kex->dh, dh_client_pub)) {
@@ -199,9 +204,9 @@
sshbuf_ptr(kex->my), sshbuf_len(kex->my),
server_host_key_blob, sbloblen,
kex->min, kex->nbits, kex->max,
- kex->dh->p, kex->dh->g,
+ dh_p, dh_g,
dh_client_pub,
- kex->dh->pub_key,
+ pub_key,
shared_secret,
hash, &hashlen)) != 0)
goto out;
@@ -227,7 +232,7 @@
/* send server hostkey, DH pubkey 'f' and signed H */
if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 ||
(r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */
+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */
(r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
Index: head/crypto/openssh/monitor.c
===================================================================
--- head/crypto/openssh/monitor.c
+++ head/crypto/openssh/monitor.c
@@ -29,7 +29,6 @@
#include <sys/types.h>
#include <sys/socket.h>
-#include "openbsd-compat/sys-tree.h"
#include <sys/wait.h>
#include <errno.h>
@@ -60,7 +59,10 @@
#include <openssl/dh.h>
#endif
+#include "openbsd-compat/sys-tree.h"
#include "openbsd-compat/sys-queue.h"
+#include "openbsd-compat/openssl-compat.h"
+
#include "atomicio.h"
#include "xmalloc.h"
#include "ssh.h"
@@ -566,6 +568,7 @@
mm_answer_moduli(int sock, struct sshbuf *m)
{
DH *dh;
+ const BIGNUM *dh_p, *dh_g;
int r;
u_int min, want, max;
@@ -590,9 +593,10 @@
return (0);
} else {
/* Send first bignum */
+ DH_get0_pqg(dh, &dh_p, NULL, &dh_g);
if ((r = sshbuf_put_u8(m, 1)) != 0 ||
- (r = sshbuf_put_bignum2(m, dh->p)) != 0 ||
- (r = sshbuf_put_bignum2(m, dh->g)) != 0)
+ (r = sshbuf_put_bignum2(m, dh_p)) != 0 ||
+ (r = sshbuf_put_bignum2(m, dh_g)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
DH_free(dh);
Index: head/crypto/openssh/openbsd-compat/Makefile.in
===================================================================
--- head/crypto/openssh/openbsd-compat/Makefile.in
+++ head/crypto/openssh/openbsd-compat/Makefile.in
@@ -85,6 +85,7 @@
getrrsetbyname-ldns.o \
kludge-fd_set.o \
openssl-compat.o \
+ libressl-api-compat.o \
xcrypt.o
PORTS= port-aix.o \
Index: head/crypto/openssh/openbsd-compat/libressl-api-compat.c
===================================================================
--- head/crypto/openssh/openbsd-compat/libressl-api-compat.c
+++ head/crypto/openssh/openbsd-compat/libressl-api-compat.c
@@ -0,0 +1,636 @@
+/* $OpenBSD: dsa_lib.c,v 1.29 2018/04/14 07:09:21 tb Exp $ */
+/* $OpenBSD: rsa_lib.c,v 1.37 2018/04/14 07:09:21 tb Exp $ */
+/* $OpenBSD: evp_lib.c,v 1.17 2018/09/12 06:35:38 djm Exp $ */
+/* $OpenBSD: dh_lib.c,v 1.32 2018/05/02 15:48:38 tb Exp $ */
+/* $OpenBSD: p_lib.c,v 1.24 2018/05/30 15:40:50 tb Exp $ */
+/* $OpenBSD: digest.c,v 1.30 2018/04/14 07:09:21 tb Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* $OpenBSD: dsa_asn1.c,v 1.22 2018/06/14 17:03:19 jsing Exp $ */
+/* $OpenBSD: ecs_asn1.c,v 1.9 2018/03/17 15:24:44 tb Exp $ */
+/* $OpenBSD: digest.c,v 1.30 2018/04/14 07:09:21 tb Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* $OpenBSD: rsa_meth.c,v 1.2 2018/09/12 06:35:38 djm Exp $ */
+/*
+ * Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#ifdef WITH_OPENSSL
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/ecdsa.h>
+#include <openssl/dh.h>
+
+#ifndef HAVE_DSA_GET0_PQG
+void
+DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+ if (p != NULL)
+ *p = d->p;
+ if (q != NULL)
+ *q = d->q;
+ if (g != NULL)
+ *g = d->g;
+}
+#endif /* HAVE_DSA_GET0_PQG */
+
+#ifndef HAVE_DSA_SET0_PQG
+int
+DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ if ((d->p == NULL && p == NULL) || (d->q == NULL && q == NULL) ||
+ (d->g == NULL && g == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(d->p);
+ d->p = p;
+ }
+ if (q != NULL) {
+ BN_free(d->q);
+ d->q = q;
+ }
+ if (g != NULL) {
+ BN_free(d->g);
+ d->g = g;
+ }
+
+ return 1;
+}
+#endif /* HAVE_DSA_SET0_PQG */
+
+#ifndef HAVE_DSA_GET0_KEY
+void
+DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+ if (pub_key != NULL)
+ *pub_key = d->pub_key;
+ if (priv_key != NULL)
+ *priv_key = d->priv_key;
+}
+#endif /* HAVE_DSA_GET0_KEY */
+
+#ifndef HAVE_DSA_SET0_KEY
+int
+DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+ if (d->pub_key == NULL && pub_key == NULL)
+ return 0;
+
+ if (pub_key != NULL) {
+ BN_free(d->pub_key);
+ d->pub_key = pub_key;
+ }
+ if (priv_key != NULL) {
+ BN_free(d->priv_key);
+ d->priv_key = priv_key;
+ }
+
+ return 1;
+}
+#endif /* HAVE_DSA_SET0_KEY */
+
+#ifndef HAVE_RSA_GET0_KEY
+void
+RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
+{
+ if (n != NULL)
+ *n = r->n;
+ if (e != NULL)
+ *e = r->e;
+ if (d != NULL)
+ *d = r->d;
+}
+#endif /* HAVE_RSA_GET0_KEY */
+
+#ifndef HAVE_RSA_SET0_KEY
+int
+RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+{
+ if ((r->n == NULL && n == NULL) || (r->e == NULL && e == NULL))
+ return 0;
+
+ if (n != NULL) {
+ BN_free(r->n);
+ r->n = n;
+ }
+ if (e != NULL) {
+ BN_free(r->e);
+ r->e = e;
+ }
+ if (d != NULL) {
+ BN_free(r->d);
+ r->d = d;
+ }
+
+ return 1;
+}
+#endif /* HAVE_RSA_SET0_KEY */
+
+#ifndef HAVE_RSA_GET0_CRT_PARAMS
+void
+RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1,
+ const BIGNUM **iqmp)
+{
+ if (dmp1 != NULL)
+ *dmp1 = r->dmp1;
+ if (dmq1 != NULL)
+ *dmq1 = r->dmq1;
+ if (iqmp != NULL)
+ *iqmp = r->iqmp;
+}
+#endif /* HAVE_RSA_GET0_CRT_PARAMS */
+
+#ifndef HAVE_RSA_SET0_CRT_PARAMS
+int
+RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
+{
+ if ((r->dmp1 == NULL && dmp1 == NULL) ||
+ (r->dmq1 == NULL && dmq1 == NULL) ||
+ (r->iqmp == NULL && iqmp == NULL))
+ return 0;
+
+ if (dmp1 != NULL) {
+ BN_free(r->dmp1);
+ r->dmp1 = dmp1;
+ }
+ if (dmq1 != NULL) {
+ BN_free(r->dmq1);
+ r->dmq1 = dmq1;
+ }
+ if (iqmp != NULL) {
+ BN_free(r->iqmp);
+ r->iqmp = iqmp;
+ }
+
+ return 1;
+}
+#endif /* HAVE_RSA_SET0_CRT_PARAMS */
+
+#ifndef HAVE_RSA_GET0_FACTORS
+void
+RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
+{
+ if (p != NULL)
+ *p = r->p;
+ if (q != NULL)
+ *q = r->q;
+}
+#endif /* HAVE_RSA_GET0_FACTORS */
+
+#ifndef HAVE_RSA_SET0_FACTORS
+int
+RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
+{
+ if ((r->p == NULL && p == NULL) || (r->q == NULL && q == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(r->p);
+ r->p = p;
+ }
+ if (q != NULL) {
+ BN_free(r->q);
+ r->q = q;
+ }
+
+ return 1;
+}
+#endif /* HAVE_RSA_SET0_FACTORS */
+
+#ifndef HAVE_EVP_CIPHER_CTX_GET_IV
+int
+EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, unsigned char *iv, size_t len)
+{
+ if (ctx == NULL)
+ return 0;
+ if (EVP_CIPHER_CTX_iv_length(ctx) < 0)
+ return 0;
+ if (len != (size_t)EVP_CIPHER_CTX_iv_length(ctx))
+ return 0;
+ if (len > EVP_MAX_IV_LENGTH)
+ return 0; /* sanity check; shouldn't happen */
+ /*
+ * Skip the memcpy entirely when the requested IV length is zero,
+ * since the iv pointer may be NULL or invalid.
+ */
+ if (len != 0) {
+ if (iv == NULL)
+ return 0;
+# ifdef HAVE_EVP_CIPHER_CTX_IV
+ memcpy(iv, EVP_CIPHER_CTX_iv(ctx), len);
+# else
+ memcpy(iv, ctx->iv, len);
+# endif /* HAVE_EVP_CIPHER_CTX_IV */
+ }
+ return 1;
+}
+#endif /* HAVE_EVP_CIPHER_CTX_GET_IV */
+
+#ifndef HAVE_EVP_CIPHER_CTX_SET_IV
+int
+EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, const unsigned char *iv, size_t len)
+{
+ if (ctx == NULL)
+ return 0;
+ if (EVP_CIPHER_CTX_iv_length(ctx) < 0)
+ return 0;
+ if (len != (size_t)EVP_CIPHER_CTX_iv_length(ctx))
+ return 0;
+ if (len > EVP_MAX_IV_LENGTH)
+ return 0; /* sanity check; shouldn't happen */
+ /*
+ * Skip the memcpy entirely when the requested IV length is zero,
+ * since the iv pointer may be NULL or invalid.
+ */
+ if (len != 0) {
+ if (iv == NULL)
+ return 0;
+# ifdef HAVE_EVP_CIPHER_CTX_IV_NOCONST
+ memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, len);
+# else
+ memcpy(ctx->iv, iv, len);
+# endif /* HAVE_EVP_CIPHER_CTX_IV_NOCONST */
+ }
+ return 1;
+}
+#endif /* HAVE_EVP_CIPHER_CTX_SET_IV */
+
+#ifndef HAVE_DSA_SIG_GET0
+void
+DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+ if (pr != NULL)
+ *pr = sig->r;
+ if (ps != NULL)
+ *ps = sig->s;
+}
+#endif /* HAVE_DSA_SIG_GET0 */
+
+#ifndef HAVE_DSA_SIG_SET0
+int
+DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+ if (r == NULL || s == NULL)
+ return 0;
+
+ BN_clear_free(sig->r);
+ sig->r = r;
+ BN_clear_free(sig->s);
+ sig->s = s;
+
+ return 1;
+}
+#endif /* HAVE_DSA_SIG_SET0 */
+
+#ifndef HAVE_ECDSA_SIG_GET0
+void
+ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+ if (pr != NULL)
+ *pr = sig->r;
+ if (ps != NULL)
+ *ps = sig->s;
+}
+#endif /* HAVE_ECDSA_SIG_GET0 */
+
+#ifndef HAVE_ECDSA_SIG_SET0
+int
+ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+ if (r == NULL || s == NULL)
+ return 0;
+
+ BN_clear_free(sig->r);
+ BN_clear_free(sig->s);
+ sig->r = r;
+ sig->s = s;
+ return 1;
+}
+#endif /* HAVE_ECDSA_SIG_SET0 */
+
+#ifndef HAVE_DH_GET0_PQG
+void
+DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+ if (p != NULL)
+ *p = dh->p;
+ if (q != NULL)
+ *q = dh->q;
+ if (g != NULL)
+ *g = dh->g;
+}
+#endif /* HAVE_DH_GET0_PQG */
+
+#ifndef HAVE_DH_SET0_PQG
+int
+DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(dh->p);
+ dh->p = p;
+ }
+ if (q != NULL) {
+ BN_free(dh->q);
+ dh->q = q;
+ }
+ if (g != NULL) {
+ BN_free(dh->g);
+ dh->g = g;
+ }
+
+ return 1;
+}
+#endif /* HAVE_DH_SET0_PQG */
+
+#ifndef HAVE_DH_GET0_KEY
+void
+DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+ if (pub_key != NULL)
+ *pub_key = dh->pub_key;
+ if (priv_key != NULL)
+ *priv_key = dh->priv_key;
+}
+#endif /* HAVE_DH_GET0_KEY */
+
+#ifndef HAVE_DH_SET0_KEY
+int
+DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+ if (pub_key != NULL) {
+ BN_free(dh->pub_key);
+ dh->pub_key = pub_key;
+ }
+ if (priv_key != NULL) {
+ BN_free(dh->priv_key);
+ dh->priv_key = priv_key;
+ }
+
+ return 1;
+}
+#endif /* HAVE_DH_SET0_KEY */
+
+#ifndef HAVE_DH_SET_LENGTH
+int
+DH_set_length(DH *dh, long length)
+{
+ if (length < 0 || length > INT_MAX)
+ return 0;
+
+ dh->length = length;
+ return 1;
+}
+#endif /* HAVE_DH_SET_LENGTH */
+
+#ifndef HAVE_RSA_METH_FREE
+void
+RSA_meth_free(RSA_METHOD *meth)
+{
+ if (meth != NULL) {
+ free((char *)meth->name);
+ free(meth);
+ }
+}
+#endif /* HAVE_RSA_METH_FREE */
+
+#ifndef HAVE_RSA_METH_DUP
+RSA_METHOD *
+RSA_meth_dup(const RSA_METHOD *meth)
+{
+ RSA_METHOD *copy;
+
+ if ((copy = calloc(1, sizeof(*copy))) == NULL)
+ return NULL;
+ memcpy(copy, meth, sizeof(*copy));
+ if ((copy->name = strdup(meth->name)) == NULL) {
+ free(copy);
+ return NULL;
+ }
+
+ return copy;
+}
+#endif /* HAVE_RSA_METH_DUP */
+
+#ifndef HAVE_RSA_METH_SET1_NAME
+int
+RSA_meth_set1_name(RSA_METHOD *meth, const char *name)
+{
+ char *copy;
+
+ if ((copy = strdup(name)) == NULL)
+ return 0;
+ free((char *)meth->name);
+ meth->name = copy;
+ return 1;
+}
+#endif /* HAVE_RSA_METH_SET1_NAME */
+
+#ifndef HAVE_RSA_METH_GET_FINISH
+int
+(*RSA_meth_get_finish(const RSA_METHOD *meth))(RSA *rsa)
+{
+ return meth->finish;
+}
+#endif /* HAVE_RSA_METH_GET_FINISH */
+
+#ifndef HAVE_RSA_METH_SET_PRIV_ENC
+int
+RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc)(int flen,
+ const unsigned char *from, unsigned char *to, RSA *rsa, int padding))
+{
+ meth->rsa_priv_enc = priv_enc;
+ return 1;
+}
+#endif /* HAVE_RSA_METH_SET_PRIV_ENC */
+
+#ifndef HAVE_RSA_METH_SET_PRIV_DEC
+int
+RSA_meth_set_priv_dec(RSA_METHOD *meth, int (*priv_dec)(int flen,
+ const unsigned char *from, unsigned char *to, RSA *rsa, int padding))
+{
+ meth->rsa_priv_dec = priv_dec;
+ return 1;
+}
+#endif /* HAVE_RSA_METH_SET_PRIV_DEC */
+
+#ifndef HAVE_RSA_METH_SET_FINISH
+int
+RSA_meth_set_finish(RSA_METHOD *meth, int (*finish)(RSA *rsa))
+{
+ meth->finish = finish;
+ return 1;
+}
+#endif /* HAVE_RSA_METH_SET_FINISH */
+
+#ifndef HAVE_EVP_PKEY_GET0_RSA
+RSA *
+EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_RSA) {
+ /* EVPerror(EVP_R_EXPECTING_AN_RSA_KEY); */
+ return NULL;
+ }
+ return pkey->pkey.rsa;
+}
+#endif /* HAVE_EVP_PKEY_GET0_RSA */
+
+#ifndef HAVE_EVP_MD_CTX_NEW
+EVP_MD_CTX *
+EVP_MD_CTX_new(void)
+{
+ return calloc(1, sizeof(EVP_MD_CTX));
+}
+#endif /* HAVE_EVP_MD_CTX_NEW */
+
+#ifndef HAVE_EVP_MD_CTX_FREE
+void
+EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+{
+ if (ctx == NULL)
+ return;
+
+ EVP_MD_CTX_cleanup(ctx);
+
+ free(ctx);
+}
+#endif /* HAVE_EVP_MD_CTX_FREE */
+
+#endif /* WITH_OPENSSL */
Index: head/crypto/openssh/openbsd-compat/openssl-compat.h
===================================================================
--- head/crypto/openssh/openbsd-compat/openssl-compat.h
+++ head/crypto/openssh/openbsd-compat/openssl-compat.h
@@ -24,6 +24,8 @@
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
+#include <openssl/ecdsa.h>
+#include <openssl/dh.h>
int ssh_compatible_openssl(long, long);
@@ -95,6 +97,140 @@
void ssh_OpenSSL_add_all_algorithms(void);
#endif /* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */
+
+/* LibreSSL/OpenSSL 1.1x API compat */
+#ifndef HAVE_DSA_GET0_PQG
+void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q,
+ const BIGNUM **g);
+#endif /* HAVE_DSA_GET0_PQG */
+
+#ifndef HAVE_DSA_SET0_PQG
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+#endif /* HAVE_DSA_SET0_PQG */
+
+#ifndef HAVE_DSA_GET0_KEY
+void DSA_get0_key(const DSA *d, const BIGNUM **pub_key,
+ const BIGNUM **priv_key);
+#endif /* HAVE_DSA_GET0_KEY */
+
+#ifndef HAVE_DSA_SET0_KEY
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key);
+#endif /* HAVE_DSA_SET0_KEY */
+
+#ifndef HAVE_EVP_CIPHER_CTX_GET_IV
+int EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx,
+ unsigned char *iv, size_t len);
+#endif /* HAVE_EVP_CIPHER_CTX_GET_IV */
+
+#ifndef HAVE_EVP_CIPHER_CTX_SET_IV
+int EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx,
+ const unsigned char *iv, size_t len);
+#endif /* HAVE_EVP_CIPHER_CTX_SET_IV */
+
+#ifndef HAVE_RSA_GET0_KEY
+void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e,
+ const BIGNUM **d);
+#endif /* HAVE_RSA_GET0_KEY */
+
+#ifndef HAVE_RSA_SET0_KEY
+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
+#endif /* HAVE_RSA_SET0_KEY */
+
+#ifndef HAVE_RSA_GET0_CRT_PARAMS
+void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1,
+ const BIGNUM **iqmp);
+#endif /* HAVE_RSA_GET0_CRT_PARAMS */
+
+#ifndef HAVE_RSA_SET0_CRT_PARAMS
+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp);
+#endif /* HAVE_RSA_SET0_CRT_PARAMS */
+
+#ifndef HAVE_RSA_GET0_FACTORS
+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q);
+#endif /* HAVE_RSA_GET0_FACTORS */
+
+#ifndef HAVE_RSA_SET0_FACTORS
+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q);
+#endif /* HAVE_RSA_SET0_FACTORS */
+
+#ifndef DSA_SIG_GET0
+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
+#endif /* DSA_SIG_GET0 */
+
+#ifndef DSA_SIG_SET0
+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s);
+#endif /* DSA_SIG_SET0 */
+
+#ifndef HAVE_ECDSA_SIG_GET0
+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
+#endif /* HAVE_ECDSA_SIG_GET0 */
+
+#ifndef HAVE_ECDSA_SIG_SET0
+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
+#endif /* HAVE_ECDSA_SIG_SET0 */
+
+#ifndef HAVE_DH_GET0_PQG
+void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q,
+ const BIGNUM **g);
+#endif /* HAVE_DH_GET0_PQG */
+
+#ifndef HAVE_DH_SET0_PQG
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+#endif /* HAVE_DH_SET0_PQG */
+
+#ifndef HAVE_DH_GET0_KEY
+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key);
+#endif /* HAVE_DH_GET0_KEY */
+
+#ifndef HAVE_DH_SET0_KEY
+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key);
+#endif /* HAVE_DH_SET0_KEY */
+
+#ifndef HAVE_DH_SET_LENGTH
+int DH_set_length(DH *dh, long length);
+#endif /* HAVE_DH_SET_LENGTH */
+
+#ifndef HAVE_RSA_METH_FREE
+void RSA_meth_free(RSA_METHOD *meth);
+#endif /* HAVE_RSA_METH_FREE */
+
+#ifndef HAVE_RSA_METH_DUP
+RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth);
+#endif /* HAVE_RSA_METH_DUP */
+
+#ifndef HAVE_RSA_METH_SET1_NAME
+int RSA_meth_set1_name(RSA_METHOD *meth, const char *name);
+#endif /* HAVE_RSA_METH_SET1_NAME */
+
+#ifndef HAVE_RSA_METH_GET_FINISH
+int (*RSA_meth_get_finish(const RSA_METHOD *meth))(RSA *rsa);
+#endif /* HAVE_RSA_METH_GET_FINISH */
+
+#ifndef HAVE_RSA_METH_SET_PRIV_ENC
+int RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc)(int flen,
+ const unsigned char *from, unsigned char *to, RSA *rsa, int padding));
+#endif /* HAVE_RSA_METH_SET_PRIV_ENC */
+
+#ifndef HAVE_RSA_METH_SET_PRIV_DEC
+int RSA_meth_set_priv_dec(RSA_METHOD *meth, int (*priv_dec)(int flen,
+ const unsigned char *from, unsigned char *to, RSA *rsa, int padding));
+#endif /* HAVE_RSA_METH_SET_PRIV_DEC */
+
+#ifndef HAVE_RSA_METH_SET_FINISH
+int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish)(RSA *rsa));
+#endif /* HAVE_RSA_METH_SET_FINISH */
+
+#ifndef HAVE_EVP_PKEY_GET0_RSA
+RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey);
+#endif /* HAVE_EVP_PKEY_GET0_RSA */
+
+#ifndef HAVE_EVP_MD_CTX_new
+EVP_MD_CTX *EVP_MD_CTX_new(void);
+#endif /* HAVE_EVP_MD_CTX_new */
+
+#ifndef HAVE_EVP_MD_CTX_free
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
+#endif /* HAVE_EVP_MD_CTX_free */
#endif /* WITH_OPENSSL */
#endif /* _OPENSSL_COMPAT_H */
Index: head/crypto/openssh/regress/unittests/sshkey/common.h
===================================================================
--- head/crypto/openssh/regress/unittests/sshkey/common.h
+++ head/crypto/openssh/regress/unittests/sshkey/common.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: common.h,v 1.1 2014/06/24 01:14:18 djm Exp $ */
+/* $OpenBSD: common.h,v 1.2 2018/09/13 09:03:20 djm Exp $ */
/*
* Helpers for key API tests
*
@@ -13,4 +13,13 @@
/* Load a bignum from a file */
BIGNUM *load_bignum(const char *name);
+
+/* Accessors for key components */
+const BIGNUM *rsa_n(struct sshkey *k);
+const BIGNUM *rsa_e(struct sshkey *k);
+const BIGNUM *rsa_p(struct sshkey *k);
+const BIGNUM *rsa_q(struct sshkey *k);
+const BIGNUM *dsa_g(struct sshkey *k);
+const BIGNUM *dsa_pub_key(struct sshkey *k);
+const BIGNUM *dsa_priv_key(struct sshkey *k);
Index: head/crypto/openssh/regress/unittests/sshkey/common.c
===================================================================
--- head/crypto/openssh/regress/unittests/sshkey/common.c
+++ head/crypto/openssh/regress/unittests/sshkey/common.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: common.c,v 1.2 2015/01/08 13:10:58 djm Exp $ */
+/* $OpenBSD: common.c,v 1.3 2018/09/13 09:03:20 djm Exp $ */
/*
* Helpers for key API tests
*
@@ -80,5 +80,82 @@
ASSERT_INT_NE(BN_hex2bn(&ret, (const char *)sshbuf_ptr(buf)), 0);
sshbuf_free(buf);
return ret;
+}
+
+const BIGNUM *
+rsa_n(struct sshkey *k)
+{
+ const BIGNUM *n = NULL;
+
+ ASSERT_PTR_NE(k, NULL);
+ ASSERT_PTR_NE(k->rsa, NULL);
+ RSA_get0_key(k->rsa, &n, NULL, NULL);
+ return n;
+}
+
+const BIGNUM *
+rsa_e(struct sshkey *k)
+{
+ const BIGNUM *e = NULL;
+
+ ASSERT_PTR_NE(k, NULL);
+ ASSERT_PTR_NE(k->rsa, NULL);
+ RSA_get0_key(k->rsa, NULL, &e, NULL);
+ return e;
+}
+
+const BIGNUM *
+rsa_p(struct sshkey *k)
+{
+ const BIGNUM *p = NULL;
+
+ ASSERT_PTR_NE(k, NULL);
+ ASSERT_PTR_NE(k->rsa, NULL);
+ RSA_get0_factors(k->rsa, &p, NULL);
+ return p;
+}
+
+const BIGNUM *
+rsa_q(struct sshkey *k)
+{
+ const BIGNUM *q = NULL;
+
+ ASSERT_PTR_NE(k, NULL);
+ ASSERT_PTR_NE(k->rsa, NULL);
+ RSA_get0_factors(k->rsa, NULL, &q);
+ return q;
+}
+
+const BIGNUM *
+dsa_g(struct sshkey *k)
+{
+ const BIGNUM *g = NULL;
+
+ ASSERT_PTR_NE(k, NULL);
+ ASSERT_PTR_NE(k->dsa, NULL);
+ DSA_get0_pqg(k->dsa, NULL, NULL, &g);
+ return g;
+}
+
+const BIGNUM *
+dsa_pub_key(struct sshkey *k)
+{
+ const BIGNUM *pub_key = NULL;
+
+ ASSERT_PTR_NE(k, NULL);
+ ASSERT_PTR_NE(k->dsa, NULL);
+ DSA_get0_key(k->dsa, &pub_key, NULL);
+ return pub_key;
+}
+
+const BIGNUM *
+dsa_priv_key(struct sshkey *k)
+{
+ const BIGNUM *priv_key = NULL;
+
+ ASSERT_PTR_NE(k, NULL);
+ ASSERT_PTR_NE(k->dsa, NULL);
+ DSA_get0_key(k->dsa, NULL, &priv_key);
+ return priv_key;
}
Index: head/crypto/openssh/regress/unittests/sshkey/test_file.c
===================================================================
--- head/crypto/openssh/regress/unittests/sshkey/test_file.c
+++ head/crypto/openssh/regress/unittests/sshkey/test_file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_file.c,v 1.6 2017/04/30 23:33:48 djm Exp $ */
+/* $OpenBSD: test_file.c,v 1.8 2018/09/13 09:03:20 djm Exp $ */
/*
* Regress test for sshkey.h key management API
*
@@ -60,9 +60,9 @@
a = load_bignum("rsa_1.param.n");
b = load_bignum("rsa_1.param.p");
c = load_bignum("rsa_1.param.q");
- ASSERT_BIGNUM_EQ(k1->rsa->n, a);
- ASSERT_BIGNUM_EQ(k1->rsa->p, b);
- ASSERT_BIGNUM_EQ(k1->rsa->q, c);
+ ASSERT_BIGNUM_EQ(rsa_n(k1), a);
+ ASSERT_BIGNUM_EQ(rsa_p(k1), b);
+ ASSERT_BIGNUM_EQ(rsa_q(k1), c);
BN_free(a);
BN_free(b);
BN_free(c);
@@ -151,9 +151,9 @@
a = load_bignum("dsa_1.param.g");
b = load_bignum("dsa_1.param.priv");
c = load_bignum("dsa_1.param.pub");
- ASSERT_BIGNUM_EQ(k1->dsa->g, a);
- ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b);
- ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c);
+ ASSERT_BIGNUM_EQ(dsa_g(k1), a);
+ ASSERT_BIGNUM_EQ(dsa_priv_key(k1), b);
+ ASSERT_BIGNUM_EQ(dsa_pub_key(k1), c);
BN_free(a);
BN_free(b);
BN_free(c);
Index: head/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
===================================================================
--- head/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
+++ head/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: test_sshkey.c,v 1.14 2018/07/13 02:13:19 djm Exp $ */
+/* $OpenBSD: test_sshkey.c,v 1.17 2018/09/13 09:03:20 djm Exp $ */
/*
* Regress test for sshkey.h key management API
*
@@ -197,9 +197,6 @@
k1 = sshkey_new(KEY_RSA);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->rsa, NULL);
- ASSERT_PTR_NE(k1->rsa->n, NULL);
- ASSERT_PTR_NE(k1->rsa->e, NULL);
- ASSERT_PTR_EQ(k1->rsa->p, NULL);
sshkey_free(k1);
TEST_DONE();
@@ -207,8 +204,6 @@
k1 = sshkey_new(KEY_DSA);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->dsa, NULL);
- ASSERT_PTR_NE(k1->dsa->g, NULL);
- ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
sshkey_free(k1);
TEST_DONE();
@@ -230,27 +225,6 @@
sshkey_free(k1);
TEST_DONE();
- TEST_START("new_private KEY_RSA");
- k1 = sshkey_new_private(KEY_RSA);
- ASSERT_PTR_NE(k1, NULL);
- ASSERT_PTR_NE(k1->rsa, NULL);
- ASSERT_PTR_NE(k1->rsa->n, NULL);
- ASSERT_PTR_NE(k1->rsa->e, NULL);
- ASSERT_PTR_NE(k1->rsa->p, NULL);
- ASSERT_INT_EQ(sshkey_add_private(k1), 0);
- sshkey_free(k1);
- TEST_DONE();
-
- TEST_START("new_private KEY_DSA");
- k1 = sshkey_new_private(KEY_DSA);
- ASSERT_PTR_NE(k1, NULL);
- ASSERT_PTR_NE(k1->dsa, NULL);
- ASSERT_PTR_NE(k1->dsa->g, NULL);
- ASSERT_PTR_NE(k1->dsa->priv_key, NULL);
- ASSERT_INT_EQ(sshkey_add_private(k1), 0);
- sshkey_free(k1);
- TEST_DONE();
-
TEST_START("generate KEY_RSA too small modulus");
ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1),
SSH_ERR_KEY_LENGTH);
@@ -285,18 +259,18 @@
ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0);
ASSERT_PTR_NE(kr, NULL);
ASSERT_PTR_NE(kr->rsa, NULL);
- ASSERT_PTR_NE(kr->rsa->n, NULL);
- ASSERT_PTR_NE(kr->rsa->e, NULL);
- ASSERT_PTR_NE(kr->rsa->p, NULL);
- ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024);
+ ASSERT_PTR_NE(rsa_n(kr), NULL);
+ ASSERT_PTR_NE(rsa_e(kr), NULL);
+ ASSERT_PTR_NE(rsa_p(kr), NULL);
+ ASSERT_INT_EQ(BN_num_bits(rsa_n(kr)), 1024);
TEST_DONE();
TEST_START("generate KEY_DSA");
ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0);
ASSERT_PTR_NE(kd, NULL);
ASSERT_PTR_NE(kd->dsa, NULL);
- ASSERT_PTR_NE(kd->dsa->g, NULL);
- ASSERT_PTR_NE(kd->dsa->priv_key, NULL);
+ ASSERT_PTR_NE(dsa_g(kd), NULL);
+ ASSERT_PTR_NE(dsa_priv_key(kd), NULL);
TEST_DONE();
#ifdef OPENSSL_HAS_ECC
@@ -323,9 +297,9 @@
ASSERT_PTR_NE(kr, k1);
ASSERT_INT_EQ(k1->type, KEY_RSA);
ASSERT_PTR_NE(k1->rsa, NULL);
- ASSERT_PTR_NE(k1->rsa->n, NULL);
- ASSERT_PTR_NE(k1->rsa->e, NULL);
- ASSERT_PTR_EQ(k1->rsa->p, NULL);
+ ASSERT_PTR_NE(rsa_n(k1), NULL);
+ ASSERT_PTR_NE(rsa_e(k1), NULL);
+ ASSERT_PTR_EQ(rsa_p(k1), NULL);
TEST_DONE();
TEST_START("equal KEY_RSA/demoted KEY_RSA");
@@ -339,8 +313,8 @@
ASSERT_PTR_NE(kd, k1);
ASSERT_INT_EQ(k1->type, KEY_DSA);
ASSERT_PTR_NE(k1->dsa, NULL);
- ASSERT_PTR_NE(k1->dsa->g, NULL);
- ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
+ ASSERT_PTR_NE(dsa_g(k1), NULL);
+ ASSERT_PTR_EQ(dsa_priv_key(k1), NULL);
TEST_DONE();
TEST_START("equal KEY_DSA/demoted KEY_DSA");
Index: head/crypto/openssh/ssh-dss.c
===================================================================
--- head/crypto/openssh/ssh-dss.c
+++ head/crypto/openssh/ssh-dss.c
@@ -43,6 +43,8 @@
#define SSHKEY_INTERNAL
#include "sshkey.h"
+#include "openbsd-compat/openssl-compat.h"
+
#define INTBLOB_LEN 20
#define SIGBLOB_LEN (2*INTBLOB_LEN)
@@ -51,6 +53,7 @@
const u_char *data, size_t datalen, u_int compat)
{
DSA_SIG *sig = NULL;
+ const BIGNUM *sig_r, *sig_s;
u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
struct sshbuf *b = NULL;
@@ -76,15 +79,16 @@
goto out;
}
- rlen = BN_num_bytes(sig->r);
- slen = BN_num_bytes(sig->s);
+ DSA_SIG_get0(sig, &sig_r, &sig_s);
+ rlen = BN_num_bytes(sig_r);
+ slen = BN_num_bytes(sig_s);
if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
ret = SSH_ERR_INTERNAL_ERROR;
goto out;
}
explicit_bzero(sigblob, SIGBLOB_LEN);
- BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
- BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen);
+ BN_bn2bin(sig_r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
+ BN_bn2bin(sig_s, sigblob + SIGBLOB_LEN - slen);
if ((b = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
@@ -118,6 +122,7 @@
const u_char *data, size_t datalen, u_int compat)
{
DSA_SIG *sig = NULL;
+ BIGNUM *sig_r = NULL, *sig_s = NULL;
u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL;
size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
int ret = SSH_ERR_INTERNAL_ERROR;
@@ -155,16 +160,21 @@
/* parse signature */
if ((sig = DSA_SIG_new()) == NULL ||
- (sig->r = BN_new()) == NULL ||
- (sig->s = BN_new()) == NULL) {
+ (sig_r = BN_new()) == NULL ||
+ (sig_s = BN_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) ||
- (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) {
+ if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig_r) == NULL) ||
+ (BN_bin2bn(sigblob + INTBLOB_LEN, INTBLOB_LEN, sig_s) == NULL)) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
+ if (!DSA_SIG_set0(sig, sig_r, sig_s)) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ sig_r = sig_s = NULL; /* transferred */
/* sha1 the data */
if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
@@ -186,6 +196,8 @@
out:
explicit_bzero(digest, sizeof(digest));
DSA_SIG_free(sig);
+ BN_clear_free(sig_r);
+ BN_clear_free(sig_s);
sshbuf_free(b);
free(ktype);
if (sigblob != NULL) {
Index: head/crypto/openssh/ssh-ecdsa.c
===================================================================
--- head/crypto/openssh/ssh-ecdsa.c
+++ head/crypto/openssh/ssh-ecdsa.c
@@ -43,12 +43,15 @@
#define SSHKEY_INTERNAL
#include "sshkey.h"
+#include "openbsd-compat/openssl-compat.h"
+
/* ARGSUSED */
int
ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat)
{
ECDSA_SIG *sig = NULL;
+ const BIGNUM *sig_r, *sig_s;
int hash_alg;
u_char digest[SSH_DIGEST_MAX_LENGTH];
size_t len, dlen;
@@ -80,8 +83,9 @@
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 ||
- (ret = sshbuf_put_bignum2(bb, sig->s)) != 0)
+ ECDSA_SIG_get0(sig, &sig_r, &sig_s);
+ if ((ret = sshbuf_put_bignum2(bb, sig_r)) != 0 ||
+ (ret = sshbuf_put_bignum2(bb, sig_s)) != 0)
goto out;
if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 ||
(ret = sshbuf_put_stringb(b, bb)) != 0)
@@ -112,6 +116,7 @@
const u_char *data, size_t datalen, u_int compat)
{
ECDSA_SIG *sig = NULL;
+ BIGNUM *sig_r = NULL, *sig_s = NULL;
int hash_alg;
u_char digest[SSH_DIGEST_MAX_LENGTH];
size_t dlen;
@@ -146,15 +151,23 @@
}
/* parse signature */
- if ((sig = ECDSA_SIG_new()) == NULL) {
+ if ((sig = ECDSA_SIG_new()) == NULL ||
+ (sig_r = BN_new()) == NULL ||
+ (sig_s = BN_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 ||
- sshbuf_get_bignum2(sigbuf, sig->s) != 0) {
+ if (sshbuf_get_bignum2(sigbuf, sig_r) != 0 ||
+ sshbuf_get_bignum2(sigbuf, sig_s) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
+ if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ sig_r = sig_s = NULL; /* transferred */
+
if (sshbuf_len(sigbuf) != 0) {
ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
@@ -180,6 +193,8 @@
sshbuf_free(sigbuf);
sshbuf_free(b);
ECDSA_SIG_free(sig);
+ BN_clear_free(sig_r);
+ BN_clear_free(sig_s);
free(ktype);
return ret;
}
Index: head/crypto/openssh/ssh-keygen.c
===================================================================
--- head/crypto/openssh/ssh-keygen.c
+++ head/crypto/openssh/ssh-keygen.c
@@ -450,7 +450,10 @@
u_int magic, i1, i2, i3, i4;
size_t slen;
u_long e;
-
+ BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
+ BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
+ BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
+ BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL;
if ((b = sshbuf_from(blob, blen)) == NULL)
fatal("%s: sshbuf_from failed", __func__);
if ((r = sshbuf_get_u32(b, &magic)) != 0)
@@ -494,11 +497,23 @@
switch (key->type) {
case KEY_DSA:
- buffer_get_bignum_bits(b, key->dsa->p);
- buffer_get_bignum_bits(b, key->dsa->g);
- buffer_get_bignum_bits(b, key->dsa->q);
- buffer_get_bignum_bits(b, key->dsa->pub_key);
- buffer_get_bignum_bits(b, key->dsa->priv_key);
+ if ((dsa_p = BN_new()) == NULL ||
+ (dsa_q = BN_new()) == NULL ||
+ (dsa_g = BN_new()) == NULL ||
+ (dsa_pub_key = BN_new()) == NULL ||
+ (dsa_priv_key = BN_new()) == NULL)
+ fatal("%s: BN_new", __func__);
+ buffer_get_bignum_bits(b, dsa_p);
+ buffer_get_bignum_bits(b, dsa_g);
+ buffer_get_bignum_bits(b, dsa_q);
+ buffer_get_bignum_bits(b, dsa_pub_key);
+ buffer_get_bignum_bits(b, dsa_priv_key);
+ if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g))
+ fatal("%s: DSA_set0_pqg failed", __func__);
+ dsa_p = dsa_q = dsa_g = NULL; /* transferred */
+ if (!DSA_set0_key(key->dsa, dsa_pub_key, dsa_priv_key))
+ fatal("%s: DSA_set0_key failed", __func__);
+ dsa_pub_key = dsa_priv_key = NULL; /* transferred */
break;
case KEY_RSA:
if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
@@ -515,18 +530,34 @@
e += e3;
debug("e %lx", e);
}
- if (!BN_set_word(key->rsa->e, e)) {
+ if ((rsa_e = BN_new()) == NULL)
+ fatal("%s: BN_new", __func__);
+ if (!BN_set_word(rsa_e, e)) {
+ BN_clear_free(rsa_e);
sshbuf_free(b);
sshkey_free(key);
return NULL;
}
- buffer_get_bignum_bits(b, key->rsa->d);
- buffer_get_bignum_bits(b, key->rsa->n);
- buffer_get_bignum_bits(b, key->rsa->iqmp);
- buffer_get_bignum_bits(b, key->rsa->q);
- buffer_get_bignum_bits(b, key->rsa->p);
- if ((r = ssh_rsa_generate_additional_parameters(key)) != 0)
+ if ((rsa_n = BN_new()) == NULL ||
+ (rsa_d = BN_new()) == NULL ||
+ (rsa_p = BN_new()) == NULL ||
+ (rsa_q = BN_new()) == NULL ||
+ (rsa_iqmp = BN_new()) == NULL)
+ fatal("%s: BN_new", __func__);
+ buffer_get_bignum_bits(b, rsa_d);
+ buffer_get_bignum_bits(b, rsa_n);
+ buffer_get_bignum_bits(b, rsa_iqmp);
+ buffer_get_bignum_bits(b, rsa_q);
+ buffer_get_bignum_bits(b, rsa_p);
+ if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, rsa_d))
+ fatal("%s: RSA_set0_key failed", __func__);
+ rsa_n = rsa_e = rsa_d = NULL; /* transferred */
+ if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q))
+ fatal("%s: RSA_set0_factors failed", __func__);
+ rsa_p = rsa_q = NULL; /* transferred */
+ if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0)
fatal("generate RSA parameters failed: %s", ssh_err(r));
+ BN_clear_free(rsa_iqmp);
break;
}
rlen = sshbuf_len(b);
@@ -634,7 +665,7 @@
identity_file);
}
fclose(fp);
- switch (EVP_PKEY_type(pubkey->type)) {
+ switch (EVP_PKEY_base_id(pubkey)) {
case EVP_PKEY_RSA:
if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed");
@@ -658,7 +689,7 @@
#endif
default:
fatal("%s: unsupported pubkey type %d", __func__,
- EVP_PKEY_type(pubkey->type));
+ EVP_PKEY_base_id(pubkey));
}
EVP_PKEY_free(pubkey);
return;
Index: head/crypto/openssh/ssh-pkcs11-client.c
===================================================================
--- head/crypto/openssh/ssh-pkcs11-client.c
+++ head/crypto/openssh/ssh-pkcs11-client.c
@@ -32,6 +32,8 @@
#include <openssl/rsa.h>
+#include "openbsd-compat/openssl-compat.h"
+
#include "pathnames.h"
#include "xmalloc.h"
#include "sshbuf.h"
@@ -156,12 +158,14 @@
static int
wrap_key(RSA *rsa)
{
- static RSA_METHOD helper_rsa;
+ static RSA_METHOD *helper_rsa;
- memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa));
- helper_rsa.name = "ssh-pkcs11-helper";
- helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt;
- RSA_set_method(rsa, &helper_rsa);
+ if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL)
+ fatal("%s: RSA_meth_dup failed", __func__);
+ if (!RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper") ||
+ !RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt))
+ fatal("%s: failed to prepare method", __func__);
+ RSA_set_method(rsa, helper_rsa);
return (0);
}
Index: head/crypto/openssh/ssh-pkcs11.c
===================================================================
--- head/crypto/openssh/ssh-pkcs11.c
+++ head/crypto/openssh/ssh-pkcs11.c
@@ -30,6 +30,7 @@
#include <dlfcn.h>
#include "openbsd-compat/sys-queue.h"
+#include "openbsd-compat/openssl-compat.h"
#include <openssl/x509.h>
@@ -67,7 +68,7 @@
struct pkcs11_provider *provider;
CK_ULONG slotidx;
int (*orig_finish)(RSA *rsa);
- RSA_METHOD rsa_method;
+ RSA_METHOD *rsa_method;
char *keyid;
int keyid_len;
};
@@ -182,6 +183,7 @@
rv = k11->orig_finish(rsa);
if (k11->provider)
pkcs11_provider_unref(k11->provider);
+ RSA_meth_free(k11->rsa_method);
free(k11->keyid);
free(k11);
}
@@ -326,13 +328,18 @@
k11->keyid = xmalloc(k11->keyid_len);
memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
}
- k11->orig_finish = def->finish;
- memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method));
- k11->rsa_method.name = "pkcs11";
- k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt;
- k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt;
- k11->rsa_method.finish = pkcs11_rsa_finish;
- RSA_set_method(rsa, &k11->rsa_method);
+ k11->rsa_method = RSA_meth_dup(def);
+ if (k11->rsa_method == NULL)
+ fatal("%s: RSA_meth_dup failed", __func__);
+ k11->orig_finish = RSA_meth_get_finish(def);
+ if (!RSA_meth_set1_name(k11->rsa_method, "pkcs11") ||
+ !RSA_meth_set_priv_enc(k11->rsa_method,
+ pkcs11_rsa_private_encrypt) ||
+ !RSA_meth_set_priv_dec(k11->rsa_method,
+ pkcs11_rsa_private_decrypt) ||
+ !RSA_meth_set_finish(k11->rsa_method, pkcs11_rsa_finish))
+ fatal("%s: setup pkcs11 method failed", __func__);
+ RSA_set_method(rsa, k11->rsa_method);
RSA_set_app_data(rsa, k11);
return (0);
}
@@ -445,6 +452,15 @@
}
static int
+have_rsa_key(const RSA *rsa)
+{
+ const BIGNUM *rsa_n, *rsa_e;
+
+ RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL);
+ return rsa_n != NULL && rsa_e != NULL;
+}
+
+static int
pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3],
struct sshkey ***keysp, int *nkeys)
@@ -512,10 +528,20 @@
if ((rsa = RSA_new()) == NULL) {
error("RSA_new failed");
} else {
- rsa->n = BN_bin2bn(attribs[1].pValue,
+ BIGNUM *rsa_n, *rsa_e;
+
+ rsa_n = BN_bin2bn(attribs[1].pValue,
attribs[1].ulValueLen, NULL);
- rsa->e = BN_bin2bn(attribs[2].pValue,
+ rsa_e = BN_bin2bn(attribs[2].pValue,
attribs[2].ulValueLen, NULL);
+ if (rsa_n != NULL && rsa_e != NULL) {
+ if (!RSA_set0_key(rsa,
+ rsa_n, rsa_e, NULL))
+ fatal("%s: set key", __func__);
+ rsa_n = rsa_e = NULL; /* transferred */
+ }
+ BN_free(rsa_n);
+ BN_free(rsa_e);
}
} else {
cp = attribs[2].pValue;
@@ -525,16 +551,16 @@
== NULL) {
error("d2i_X509 failed");
} else if ((evp = X509_get_pubkey(x509)) == NULL ||
- evp->type != EVP_PKEY_RSA ||
- evp->pkey.rsa == NULL) {
+ EVP_PKEY_base_id(evp) != EVP_PKEY_RSA ||
+ EVP_PKEY_get0_RSA(evp) == NULL) {
debug("X509_get_pubkey failed or no rsa");
- } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa))
- == NULL) {
+ } else if ((rsa = RSAPublicKey_dup(
+ EVP_PKEY_get0_RSA(evp))) == NULL) {
error("RSAPublicKey_dup");
}
X509_free(x509);
}
- if (rsa && rsa->n && rsa->e &&
+ if (rsa && have_rsa_key(rsa) &&
pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed");
Index: head/crypto/openssh/ssh-rsa.c
===================================================================
--- head/crypto/openssh/ssh-rsa.c
+++ head/crypto/openssh/ssh-rsa.c
@@ -35,6 +35,8 @@
#include "digest.h"
#include "log.h"
+#include "openbsd-compat/openssl-compat.h"
+
static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
static const char *
@@ -104,38 +106,55 @@
}
int
-ssh_rsa_generate_additional_parameters(struct sshkey *key)
+ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)
{
- BIGNUM *aux = NULL;
+ const BIGNUM *rsa_p, *rsa_q, *rsa_d;
+ BIGNUM *aux = NULL, *d_consttime = NULL;
+ BIGNUM *rsa_dmq1 = NULL, *rsa_dmp1 = NULL, *rsa_iqmp = NULL;
BN_CTX *ctx = NULL;
- BIGNUM d;
int r;
if (key == NULL || key->rsa == NULL ||
sshkey_type_plain(key->type) != KEY_RSA)
return SSH_ERR_INVALID_ARGUMENT;
+ RSA_get0_key(key->rsa, NULL, NULL, &rsa_d);
+ RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
+
if ((ctx = BN_CTX_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
- if ((aux = BN_new()) == NULL) {
+ if ((aux = BN_new()) == NULL ||
+ (rsa_dmq1 = BN_new()) == NULL ||
+ (rsa_dmp1 = BN_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if ((d_consttime = BN_dup(rsa_d)) == NULL ||
+ (rsa_iqmp = BN_dup(iqmp)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
BN_set_flags(aux, BN_FLG_CONSTTIME);
+ BN_set_flags(d_consttime, BN_FLG_CONSTTIME);
- BN_init(&d);
- BN_with_flags(&d, key->rsa->d, BN_FLG_CONSTTIME);
-
- if ((BN_sub(aux, key->rsa->q, BN_value_one()) == 0) ||
- (BN_mod(key->rsa->dmq1, &d, aux, ctx) == 0) ||
- (BN_sub(aux, key->rsa->p, BN_value_one()) == 0) ||
- (BN_mod(key->rsa->dmp1, &d, aux, ctx) == 0)) {
+ if ((BN_sub(aux, rsa_q, BN_value_one()) == 0) ||
+ (BN_mod(rsa_dmq1, d_consttime, aux, ctx) == 0) ||
+ (BN_sub(aux, rsa_p, BN_value_one()) == 0) ||
+ (BN_mod(rsa_dmp1, d_consttime, aux, ctx) == 0)) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
+ if (!RSA_set0_crt_params(key->rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; /* transferred */
+ /* success */
r = 0;
out:
BN_clear_free(aux);
+ BN_clear_free(d_consttime);
+ BN_clear_free(rsa_dmp1);
+ BN_clear_free(rsa_dmq1);
+ BN_clear_free(rsa_iqmp);
BN_CTX_free(ctx);
return r;
}
@@ -145,6 +164,7 @@
ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, const char *alg_ident)
{
+ const BIGNUM *rsa_n;
u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
size_t slen = 0;
u_int dlen, len;
@@ -163,7 +183,8 @@
if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
sshkey_type_plain(key->type) != KEY_RSA)
return SSH_ERR_INVALID_ARGUMENT;
- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
+ RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
+ if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
return SSH_ERR_KEY_LENGTH;
slen = RSA_size(key->rsa);
if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
@@ -225,6 +246,7 @@
const u_char *sig, size_t siglen, const u_char *data, size_t datalen,
const char *alg)
{
+ const BIGNUM *rsa_n;
char *sigtype = NULL;
int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
size_t len = 0, diff, modlen, dlen;
@@ -235,7 +257,8 @@
sshkey_type_plain(key->type) != KEY_RSA ||
sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
+ RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
+ if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
return SSH_ERR_KEY_LENGTH;
if ((b = sshbuf_from(sig, siglen)) == NULL)
Index: head/crypto/openssh/sshd.c
===================================================================
--- head/crypto/openssh/sshd.c
+++ head/crypto/openssh/sshd.c
@@ -514,8 +514,8 @@
for (i = 0; i < options.num_host_key_files; i++) {
if (sensitive_data.host_keys[i]) {
- if ((r = sshkey_demote(sensitive_data.host_keys[i],
- &tmp)) != 0)
+ if ((r = sshkey_from_private(
+ sensitive_data.host_keys[i], &tmp)) != 0)
fatal("could not demote host %s key: %s",
sshkey_type(sensitive_data.host_keys[i]),
ssh_err(r));
@@ -1798,7 +1798,7 @@
error("Error loading host key \"%s\": %s",
options.host_key_files[i], ssh_err(r));
if (pubkey == NULL && key != NULL)
- if ((r = sshkey_demote(key, &pubkey)) != 0)
+ if ((r = sshkey_from_private(key, &pubkey)) != 0)
fatal("Could not demote key: \"%s\": %s",
options.host_key_files[i], ssh_err(r));
sensitive_data.host_keys[i] = key;
Index: head/crypto/openssh/sshkey.h
===================================================================
--- head/crypto/openssh/sshkey.h
+++ head/crypto/openssh/sshkey.h
@@ -39,6 +39,7 @@
# define EC_POINT void
# endif /* OPENSSL_HAS_ECC */
#else /* WITH_OPENSSL */
+# define BIGNUM void
# define RSA void
# define DSA void
# define EC_KEY void
@@ -126,10 +127,8 @@
#define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES
struct sshkey *sshkey_new(int);
-int sshkey_add_private(struct sshkey *);
-struct sshkey *sshkey_new_private(int);
+struct sshkey *sshkey_new_private(int); /* XXX garbage collect */
void sshkey_free(struct sshkey *);
-int sshkey_demote(const struct sshkey *, struct sshkey **);
int sshkey_equal_public(const struct sshkey *,
const struct sshkey *);
int sshkey_equal(const struct sshkey *, const struct sshkey *);
@@ -218,7 +217,7 @@
const char *passphrase, struct sshkey **keyp, char **commentp);
/* XXX should be internal, but used by ssh-keygen */
-int ssh_rsa_generate_additional_parameters(struct sshkey *);
+int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *);
/* stateful keys (e.g. XMSS) */
#ifdef NO_ATTRIBUTE_ON_PROTOTYPE_ARGS
Index: head/crypto/openssh/sshkey.c
===================================================================
--- head/crypto/openssh/sshkey.c
+++ head/crypto/openssh/sshkey.c
@@ -60,6 +60,8 @@
#include "xmss_fast.h"
+#include "openbsd-compat/openssl-compat.h"
+
/* openssh private key file format */
#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n"
#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n"
@@ -288,14 +290,24 @@
u_int
sshkey_size(const struct sshkey *k)
{
+#ifdef WITH_OPENSSL
+ const BIGNUM *rsa_n, *dsa_p;
+#endif /* WITH_OPENSSL */
+
switch (k->type) {
#ifdef WITH_OPENSSL
case KEY_RSA:
case KEY_RSA_CERT:
- return BN_num_bits(k->rsa->n);
+ if (k->rsa == NULL)
+ return 0;
+ RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);
+ return BN_num_bits(rsa_n);
case KEY_DSA:
case KEY_DSA_CERT:
- return BN_num_bits(k->dsa->p);
+ if (k->dsa == NULL)
+ return 0;
+ DSA_get0_pqg(k->dsa, &dsa_p, NULL, NULL);
+ return BN_num_bits(dsa_p);
case KEY_ECDSA:
case KEY_ECDSA_CERT:
return sshkey_curve_nid_to_bits(k->ecdsa_nid);
@@ -500,10 +512,7 @@
#ifdef WITH_OPENSSL
case KEY_RSA:
case KEY_RSA_CERT:
- if ((rsa = RSA_new()) == NULL ||
- (rsa->n = BN_new()) == NULL ||
- (rsa->e = BN_new()) == NULL) {
- RSA_free(rsa);
+ if ((rsa = RSA_new()) == NULL) {
free(k);
return NULL;
}
@@ -511,12 +520,7 @@
break;
case KEY_DSA:
case KEY_DSA_CERT:
- if ((dsa = DSA_new()) == NULL ||
- (dsa->p = BN_new()) == NULL ||
- (dsa->q = BN_new()) == NULL ||
- (dsa->g = BN_new()) == NULL ||
- (dsa->pub_key = BN_new()) == NULL) {
- DSA_free(dsa);
+ if ((dsa = DSA_new()) == NULL) {
free(k);
return NULL;
}
@@ -550,47 +554,7 @@
return k;
}
-int
-sshkey_add_private(struct sshkey *k)
-{
- switch (k->type) {
-#ifdef WITH_OPENSSL
- case KEY_RSA:
- case KEY_RSA_CERT:
-#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
- if (bn_maybe_alloc_failed(k->rsa->d) ||
- bn_maybe_alloc_failed(k->rsa->iqmp) ||
- bn_maybe_alloc_failed(k->rsa->q) ||
- bn_maybe_alloc_failed(k->rsa->p) ||
- bn_maybe_alloc_failed(k->rsa->dmq1) ||
- bn_maybe_alloc_failed(k->rsa->dmp1))
- return SSH_ERR_ALLOC_FAIL;
- break;
- case KEY_DSA:
- case KEY_DSA_CERT:
- if (bn_maybe_alloc_failed(k->dsa->priv_key))
- return SSH_ERR_ALLOC_FAIL;
- break;
-#undef bn_maybe_alloc_failed
- case KEY_ECDSA:
- case KEY_ECDSA_CERT:
- /* Cannot do anything until we know the group */
- break;
-#endif /* WITH_OPENSSL */
- case KEY_ED25519:
- case KEY_ED25519_CERT:
- case KEY_XMSS:
- case KEY_XMSS_CERT:
- /* no need to prealloc */
- break;
- case KEY_UNSPEC:
- break;
- default:
- return SSH_ERR_INVALID_ARGUMENT;
- }
- return 0;
-}
-
+/* XXX garbage-collect this API */
struct sshkey *
sshkey_new_private(int type)
{
@@ -598,10 +562,6 @@
if (k == NULL)
return NULL;
- if (sshkey_add_private(k) != 0) {
- sshkey_free(k);
- return NULL;
- }
return k;
}
@@ -683,9 +643,15 @@
int
sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
{
-#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
+#if defined(WITH_OPENSSL)
+ const BIGNUM *rsa_e_a, *rsa_n_a;
+ const BIGNUM *rsa_e_b, *rsa_n_b;
+ const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a;
+ const BIGNUM *dsa_p_b, *dsa_q_b, *dsa_g_b, *dsa_pub_key_b;
+# if defined(OPENSSL_HAS_ECC)
BN_CTX *bnctx;
-#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
+# endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
if (a == NULL || b == NULL ||
sshkey_type_plain(a->type) != sshkey_type_plain(b->type))
@@ -695,16 +661,24 @@
#ifdef WITH_OPENSSL
case KEY_RSA_CERT:
case KEY_RSA:
- return a->rsa != NULL && b->rsa != NULL &&
- BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
- BN_cmp(a->rsa->n, b->rsa->n) == 0;
+ if (a->rsa == NULL || b->rsa == NULL)
+ return 0;
+ RSA_get0_key(a->rsa, &rsa_n_a, &rsa_e_a, NULL);
+ RSA_get0_key(b->rsa, &rsa_n_b, &rsa_e_b, NULL);
+ return BN_cmp(rsa_e_a, rsa_e_b) == 0 &&
+ BN_cmp(rsa_n_a, rsa_n_b) == 0;
case KEY_DSA_CERT:
case KEY_DSA:
- return a->dsa != NULL && b->dsa != NULL &&
- BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
- BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
- BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
- BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
+ if (a->dsa == NULL || b->dsa == NULL)
+ return 0;
+ DSA_get0_pqg(a->dsa, &dsa_p_a, &dsa_q_a, &dsa_g_a);
+ DSA_get0_pqg(b->dsa, &dsa_p_b, &dsa_q_b, &dsa_g_b);
+ DSA_get0_key(a->dsa, &dsa_pub_key_a, NULL);
+ DSA_get0_key(b->dsa, &dsa_pub_key_b, NULL);
+ return BN_cmp(dsa_p_a, dsa_p_b) == 0 &&
+ BN_cmp(dsa_q_a, dsa_q_b) == 0 &&
+ BN_cmp(dsa_g_a, dsa_g_b) == 0 &&
+ BN_cmp(dsa_pub_key_a, dsa_pub_key_b) == 0;
# ifdef OPENSSL_HAS_ECC
case KEY_ECDSA_CERT:
case KEY_ECDSA:
@@ -761,6 +735,9 @@
{
int type, ret = SSH_ERR_INTERNAL_ERROR;
const char *typename;
+#ifdef WITH_OPENSSL
+ const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
+#endif /* WITH_OPENSSL */
if (key == NULL)
return SSH_ERR_INVALID_ARGUMENT;
@@ -793,11 +770,13 @@
case KEY_DSA:
if (key->dsa == NULL)
return SSH_ERR_INVALID_ARGUMENT;
+ DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
+ DSA_get0_key(key->dsa, &dsa_pub_key, NULL);
if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
- (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||
- (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||
- (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||
- (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0)
+ (ret = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
+ (ret = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
+ (ret = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
+ (ret = sshbuf_put_bignum2(b, dsa_pub_key)) != 0)
return ret;
break;
# ifdef OPENSSL_HAS_ECC
@@ -814,9 +793,10 @@
case KEY_RSA:
if (key->rsa == NULL)
return SSH_ERR_INVALID_ARGUMENT;
+ RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL);
if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
- (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||
- (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0)
+ (ret = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
+ (ret = sshbuf_put_bignum2(b, rsa_n)) != 0)
return ret;
break;
#endif /* WITH_OPENSSL */
@@ -1749,60 +1729,95 @@
sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
{
struct sshkey *n = NULL;
- int ret = SSH_ERR_INTERNAL_ERROR;
+ int r = SSH_ERR_INTERNAL_ERROR;
+#ifdef WITH_OPENSSL
+ const BIGNUM *rsa_n, *rsa_e;
+ BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL;
+ const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
+ BIGNUM *dsa_p_dup = NULL, *dsa_q_dup = NULL, *dsa_g_dup = NULL;
+ BIGNUM *dsa_pub_key_dup = NULL;
+#endif /* WITH_OPENSSL */
*pkp = NULL;
switch (k->type) {
#ifdef WITH_OPENSSL
case KEY_DSA:
case KEY_DSA_CERT:
- if ((n = sshkey_new(k->type)) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
- (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
- (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||
- (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) {
- sshkey_free(n);
- return SSH_ERR_ALLOC_FAIL;
+ if ((n = sshkey_new(k->type)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
}
+
+ DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g);
+ DSA_get0_key(k->dsa, &dsa_pub_key, NULL);
+ if ((dsa_p_dup = BN_dup(dsa_p)) == NULL ||
+ (dsa_q_dup = BN_dup(dsa_q)) == NULL ||
+ (dsa_g_dup = BN_dup(dsa_g)) == NULL ||
+ (dsa_pub_key_dup = BN_dup(dsa_pub_key)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (!DSA_set0_pqg(n->dsa, dsa_p_dup, dsa_q_dup, dsa_g_dup)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ dsa_p_dup = dsa_q_dup = dsa_g_dup = NULL; /* transferred */
+ if (!DSA_set0_key(n->dsa, dsa_pub_key_dup, NULL)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ dsa_pub_key_dup = NULL; /* transferred */
+
break;
# ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
case KEY_ECDSA_CERT:
- if ((n = sshkey_new(k->type)) == NULL)
- return SSH_ERR_ALLOC_FAIL;
+ if ((n = sshkey_new(k->type)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
n->ecdsa_nid = k->ecdsa_nid;
n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
if (n->ecdsa == NULL) {
- sshkey_free(n);
- return SSH_ERR_ALLOC_FAIL;
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
}
if (EC_KEY_set_public_key(n->ecdsa,
EC_KEY_get0_public_key(k->ecdsa)) != 1) {
- sshkey_free(n);
- return SSH_ERR_LIBCRYPTO_ERROR;
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
}
break;
# endif /* OPENSSL_HAS_ECC */
case KEY_RSA:
case KEY_RSA_CERT:
- if ((n = sshkey_new(k->type)) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
- (BN_copy(n->rsa->e, k->rsa->e) == NULL)) {
- sshkey_free(n);
- return SSH_ERR_ALLOC_FAIL;
+ if ((n = sshkey_new(k->type)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
}
+ RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL);
+ if ((rsa_n_dup = BN_dup(rsa_n)) == NULL ||
+ (rsa_e_dup = BN_dup(rsa_e)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (!RSA_set0_key(n->rsa, rsa_n_dup, rsa_e_dup, NULL)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ rsa_n_dup = rsa_e_dup = NULL; /* transferred */
break;
#endif /* WITH_OPENSSL */
case KEY_ED25519:
case KEY_ED25519_CERT:
- if ((n = sshkey_new(k->type)) == NULL)
- return SSH_ERR_ALLOC_FAIL;
+ if ((n = sshkey_new(k->type)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
if (k->ed25519_pk != NULL) {
if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
- sshkey_free(n);
- return SSH_ERR_ALLOC_FAIL;
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
}
memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
}
@@ -1810,37 +1825,48 @@
#ifdef WITH_XMSS
case KEY_XMSS:
case KEY_XMSS_CERT:
- if ((n = sshkey_new(k->type)) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- if ((ret = sshkey_xmss_init(n, k->xmss_name)) != 0) {
- sshkey_free(n);
- return ret;
+ if ((n = sshkey_new(k->type)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
}
+ if ((r = sshkey_xmss_init(n, k->xmss_name)) != 0)
+ goto out;
if (k->xmss_pk != NULL) {
size_t pklen = sshkey_xmss_pklen(k);
if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) {
- sshkey_free(n);
- return SSH_ERR_INTERNAL_ERROR;
+ r = SSH_ERR_INTERNAL_ERROR;
+ goto out;
}
if ((n->xmss_pk = malloc(pklen)) == NULL) {
- sshkey_free(n);
- return SSH_ERR_ALLOC_FAIL;
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
}
memcpy(n->xmss_pk, k->xmss_pk, pklen);
}
break;
#endif /* WITH_XMSS */
default:
- return SSH_ERR_KEY_TYPE_UNKNOWN;
+ r = SSH_ERR_KEY_TYPE_UNKNOWN;
+ goto out;
}
- if (sshkey_is_cert(k)) {
- if ((ret = sshkey_cert_copy(k, n)) != 0) {
- sshkey_free(n);
- return ret;
- }
- }
+ if (sshkey_is_cert(k) && (r = sshkey_cert_copy(k, n)) != 0)
+ goto out;
+ /* success */
*pkp = n;
- return 0;
+ n = NULL;
+ r = 0;
+ out:
+ sshkey_free(n);
+#ifdef WITH_OPENSSL
+ BN_clear_free(rsa_n_dup);
+ BN_clear_free(rsa_e_dup);
+ BN_clear_free(dsa_p_dup);
+ BN_clear_free(dsa_q_dup);
+ BN_clear_free(dsa_g_dup);
+ BN_clear_free(dsa_pub_key_dup);
+#endif
+
+ return r;
}
static int
@@ -1966,7 +1992,20 @@
return ret;
}
+#ifdef WITH_OPENSSL
static int
+check_rsa_length(const RSA *rsa)
+{
+ const BIGNUM *rsa_n;
+
+ RSA_get0_key(rsa, &rsa_n, NULL, NULL);
+ if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
+ return SSH_ERR_KEY_LENGTH;
+ return 0;
+}
+#endif
+
+static int
sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
int allow_cert)
{
@@ -1976,9 +2015,13 @@
size_t len;
u_char *pk = NULL;
struct sshbuf *copy;
-#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
+#if defined(WITH_OPENSSL)
+ BIGNUM *rsa_n = NULL, *rsa_e = NULL;
+ BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_pub_key = NULL;
+# if defined(OPENSSL_HAS_ECC)
EC_POINT *q = NULL;
-#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
+# endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
#ifdef DEBUG_PK /* XXX */
sshbuf_dump(b, stderr);
@@ -2013,15 +2056,23 @@
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (sshbuf_get_bignum2(b, key->rsa->e) != 0 ||
- sshbuf_get_bignum2(b, key->rsa->n) != 0) {
+ if ((rsa_e = BN_new()) == NULL ||
+ (rsa_n = BN_new()) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (sshbuf_get_bignum2(b, rsa_e) != 0 ||
+ sshbuf_get_bignum2(b, rsa_n) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
- ret = SSH_ERR_KEY_LENGTH;
+ if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
+ rsa_n = rsa_e = NULL; /* transferred */
+ if ((ret = check_rsa_length(key->rsa)) != 0)
+ goto out;
#ifdef DEBUG_PK
RSA_print_fp(stderr, key->rsa, 8);
#endif
@@ -2038,13 +2089,30 @@
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (sshbuf_get_bignum2(b, key->dsa->p) != 0 ||
- sshbuf_get_bignum2(b, key->dsa->q) != 0 ||
- sshbuf_get_bignum2(b, key->dsa->g) != 0 ||
- sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) {
+ if ((dsa_p = BN_new()) == NULL ||
+ (dsa_q = BN_new()) == NULL ||
+ (dsa_g = BN_new()) == NULL ||
+ (dsa_pub_key = BN_new()) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (sshbuf_get_bignum2(b, dsa_p) != 0 ||
+ sshbuf_get_bignum2(b, dsa_q) != 0 ||
+ sshbuf_get_bignum2(b, dsa_g) != 0 ||
+ sshbuf_get_bignum2(b, dsa_pub_key) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
+ if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g)) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ dsa_p = dsa_q = dsa_g = NULL; /* transferred */
+ if (!DSA_set0_key(key->dsa, dsa_pub_key, NULL)) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ dsa_pub_key = NULL; /* transferred */
#ifdef DEBUG_PK
DSA_print_fp(stderr, key->dsa, 8);
#endif
@@ -2178,9 +2246,17 @@
free(ktype);
free(curve);
free(pk);
-#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
+#if defined(WITH_OPENSSL)
+ BN_clear_free(rsa_n);
+ BN_clear_free(rsa_e);
+ BN_clear_free(dsa_p);
+ BN_clear_free(dsa_q);
+ BN_clear_free(dsa_g);
+ BN_clear_free(dsa_pub_key);
+# if defined(OPENSSL_HAS_ECC)
EC_POINT_free(q);
-#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
+# endif /* OPENSSL_HAS_ECC */
+#endif /* WITH_OPENSSL */
return ret;
}
@@ -2361,120 +2437,6 @@
}
}
-/* Converts a private to a public key */
-int
-sshkey_demote(const struct sshkey *k, struct sshkey **dkp)
-{
- struct sshkey *pk;
- int ret = SSH_ERR_INTERNAL_ERROR;
-
- *dkp = NULL;
- if ((pk = calloc(1, sizeof(*pk))) == NULL)
- return SSH_ERR_ALLOC_FAIL;
- pk->type = k->type;
- pk->flags = k->flags;
- pk->ecdsa_nid = k->ecdsa_nid;
- pk->dsa = NULL;
- pk->ecdsa = NULL;
- pk->rsa = NULL;
- pk->ed25519_pk = NULL;
- pk->ed25519_sk = NULL;
- pk->xmss_pk = NULL;
- pk->xmss_sk = NULL;
-
- switch (k->type) {
-#ifdef WITH_OPENSSL
- case KEY_RSA_CERT:
- if ((ret = sshkey_cert_copy(k, pk)) != 0)
- goto fail;
- /* FALLTHROUGH */
- case KEY_RSA:
- if ((pk->rsa = RSA_new()) == NULL ||
- (pk->rsa->e = BN_dup(k->rsa->e)) == NULL ||
- (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto fail;
- }
- break;
- case KEY_DSA_CERT:
- if ((ret = sshkey_cert_copy(k, pk)) != 0)
- goto fail;
- /* FALLTHROUGH */
- case KEY_DSA:
- if ((pk->dsa = DSA_new()) == NULL ||
- (pk->dsa->p = BN_dup(k->dsa->p)) == NULL ||
- (pk->dsa->q = BN_dup(k->dsa->q)) == NULL ||
- (pk->dsa->g = BN_dup(k->dsa->g)) == NULL ||
- (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto fail;
- }
- break;
- case KEY_ECDSA_CERT:
- if ((ret = sshkey_cert_copy(k, pk)) != 0)
- goto fail;
- /* FALLTHROUGH */
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA:
- pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid);
- if (pk->ecdsa == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto fail;
- }
- if (EC_KEY_set_public_key(pk->ecdsa,
- EC_KEY_get0_public_key(k->ecdsa)) != 1) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto fail;
- }
- break;
-# endif /* OPENSSL_HAS_ECC */
-#endif /* WITH_OPENSSL */
- case KEY_ED25519_CERT:
- if ((ret = sshkey_cert_copy(k, pk)) != 0)
- goto fail;
- /* FALLTHROUGH */
- case KEY_ED25519:
- if (k->ed25519_pk != NULL) {
- if ((pk->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto fail;
- }
- memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
- }
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS_CERT:
- if ((ret = sshkey_cert_copy(k, pk)) != 0)
- goto fail;
- /* FALLTHROUGH */
- case KEY_XMSS:
- if ((ret = sshkey_xmss_init(pk, k->xmss_name)) != 0)
- goto fail;
- if (k->xmss_pk != NULL) {
- size_t pklen = sshkey_xmss_pklen(k);
-
- if (pklen == 0 || sshkey_xmss_pklen(pk) != pklen) {
- ret = SSH_ERR_INTERNAL_ERROR;
- goto fail;
- }
- if ((pk->xmss_pk = malloc(pklen)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto fail;
- }
- memcpy(pk->xmss_pk, k->xmss_pk, pklen);
- }
- break;
-#endif /* WITH_XMSS */
- default:
- ret = SSH_ERR_KEY_TYPE_UNKNOWN;
- fail:
- sshkey_free(pk);
- return ret;
- }
- *dkp = pk;
- return 0;
-}
-
/* Convert a plain key to their _CERT equivalent */
int
sshkey_to_certified(struct sshkey *k)
@@ -2532,6 +2494,9 @@
size_t i, ca_len, sig_len;
int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *cert;
+#ifdef WITH_OPENSSL
+ const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
+#endif /* WITH_OPENSSL */
if (k == NULL || k->cert == NULL ||
k->cert->certblob == NULL || ca == NULL)
@@ -2558,10 +2523,12 @@
switch (k->type) {
#ifdef WITH_OPENSSL
case KEY_DSA_CERT:
- if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 ||
- (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 ||
- (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 ||
- (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0)
+ DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g);
+ DSA_get0_key(k->dsa, &dsa_pub_key, NULL);
+ if ((ret = sshbuf_put_bignum2(cert, dsa_p)) != 0 ||
+ (ret = sshbuf_put_bignum2(cert, dsa_q)) != 0 ||
+ (ret = sshbuf_put_bignum2(cert, dsa_g)) != 0 ||
+ (ret = sshbuf_put_bignum2(cert, dsa_pub_key)) != 0)
goto out;
break;
# ifdef OPENSSL_HAS_ECC
@@ -2575,8 +2542,9 @@
break;
# endif /* OPENSSL_HAS_ECC */
case KEY_RSA_CERT:
- if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 ||
- (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0)
+ RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL);
+ if ((ret = sshbuf_put_bignum2(cert, rsa_e)) != 0 ||
+ (ret = sshbuf_put_bignum2(cert, rsa_n)) != 0)
goto out;
break;
#endif /* WITH_OPENSSL */
@@ -2758,18 +2726,25 @@
enum sshkey_serialize_rep opts)
{
int r = SSH_ERR_INTERNAL_ERROR;
+#ifdef WITH_OPENSSL
+ const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q;
+ const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key;
+#endif /* WITH_OPENSSL */
if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
goto out;
switch (key->type) {
#ifdef WITH_OPENSSL
case KEY_RSA:
- if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
+ RSA_get0_key(key->rsa, &rsa_n, &rsa_e, &rsa_d);
+ RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
+ RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp);
+ if ((r = sshbuf_put_bignum2(b, rsa_n)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_d)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_p)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_q)) != 0)
goto out;
break;
case KEY_RSA_CERT:
@@ -2777,19 +2752,24 @@
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
+ RSA_get0_key(key->rsa, NULL, NULL, &rsa_d);
+ RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
+ RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp);
if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
+ (r = sshbuf_put_bignum2(b, rsa_d)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_p)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_q)) != 0)
goto out;
break;
case KEY_DSA:
- if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
+ DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
+ DSA_get0_key(key->dsa, &dsa_pub_key, &dsa_priv_key);
+ if ((r = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
+ (r = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
+ (r = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
+ (r = sshbuf_put_bignum2(b, dsa_pub_key)) != 0 ||
+ (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0)
goto out;
break;
case KEY_DSA_CERT:
@@ -2797,8 +2777,9 @@
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
+ DSA_get0_key(key->dsa, NULL, &dsa_priv_key);
if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
- (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
+ (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0)
goto out;
break;
# ifdef OPENSSL_HAS_ECC
@@ -2899,6 +2880,10 @@
u_char *xmss_pk = NULL, *xmss_sk = NULL;
#ifdef WITH_OPENSSL
BIGNUM *exponent = NULL;
+ BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
+ BIGNUM *rsa_iqmp = NULL, *rsa_p = NULL, *rsa_q = NULL;
+ BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
+ BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
#endif /* WITH_OPENSSL */
if (kp != NULL)
@@ -2913,18 +2898,44 @@
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
+ if ((dsa_p = BN_new()) == NULL ||
+ (dsa_q = BN_new()) == NULL ||
+ (dsa_g = BN_new()) == NULL ||
+ (dsa_pub_key = BN_new()) == NULL ||
+ (dsa_priv_key = BN_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
goto out;
+ }
+ if ((r = sshbuf_get_bignum2(buf, dsa_p)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, dsa_q)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, dsa_g)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, dsa_pub_key)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, dsa_priv_key)) != 0)
+ goto out;
+ if (!DSA_set0_pqg(k->dsa, dsa_p, dsa_q, dsa_g)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ dsa_p = dsa_q = dsa_g = NULL; /* transferred */
+ if (!DSA_set0_key(k->dsa, dsa_pub_key, dsa_priv_key)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ dsa_pub_key = dsa_priv_key = NULL; /* transferred */
break;
case KEY_DSA_CERT:
+ if ((dsa_priv_key = BN_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
if ((r = sshkey_froms(buf, &k)) != 0 ||
- (r = sshkey_add_private(k)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
+ (r = sshbuf_get_bignum2(buf, dsa_priv_key)) != 0)
goto out;
+ if (!DSA_set0_key(k->dsa, NULL, dsa_priv_key)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ dsa_priv_key = NULL; /* transferred */
break;
# ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
@@ -2965,7 +2976,6 @@
goto out;
}
if ((r = sshkey_froms(buf, &k)) != 0 ||
- (r = sshkey_add_private(k)) != 0 ||
(r = sshbuf_get_bignum2(buf, exponent)) != 0)
goto out;
if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
@@ -2983,32 +2993,65 @@
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
- (r = ssh_rsa_generate_additional_parameters(k)) != 0)
+ if ((rsa_n = BN_new()) == NULL ||
+ (rsa_e = BN_new()) == NULL ||
+ (rsa_d = BN_new()) == NULL ||
+ (rsa_iqmp = BN_new()) == NULL ||
+ (rsa_p = BN_new()) == NULL ||
+ (rsa_q = BN_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
goto out;
- if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
- r = SSH_ERR_KEY_LENGTH;
+ }
+ if ((r = sshbuf_get_bignum2(buf, rsa_n)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, rsa_e)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, rsa_d)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, rsa_iqmp)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, rsa_p)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, rsa_q)) != 0)
goto out;
+ if (!RSA_set0_key(k->rsa, rsa_n, rsa_e, rsa_d)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
}
+ rsa_n = rsa_e = rsa_d = NULL; /* transferred */
+ if (!RSA_set0_factors(k->rsa, rsa_p, rsa_q)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ rsa_p = rsa_q = NULL; /* transferred */
+ if ((r = check_rsa_length(k->rsa)) != 0)
+ goto out;
+ if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)
+ goto out;
break;
case KEY_RSA_CERT:
+ if ((rsa_d = BN_new()) == NULL ||
+ (rsa_iqmp = BN_new()) == NULL ||
+ (rsa_p = BN_new()) == NULL ||
+ (rsa_q = BN_new()) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
if ((r = sshkey_froms(buf, &k)) != 0 ||
- (r = sshkey_add_private(k)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||
- (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
- (r = ssh_rsa_generate_additional_parameters(k)) != 0)
+ (r = sshbuf_get_bignum2(buf, rsa_d)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, rsa_iqmp)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, rsa_p)) != 0 ||
+ (r = sshbuf_get_bignum2(buf, rsa_q)) != 0)
goto out;
- if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
- r = SSH_ERR_KEY_LENGTH;
+ if (!RSA_set0_key(k->rsa, NULL, NULL, rsa_d)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
+ rsa_d = NULL; /* transferred */
+ if (!RSA_set0_factors(k->rsa, rsa_p, rsa_q)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ rsa_p = rsa_q = NULL; /* transferred */
+ if ((r = check_rsa_length(k->rsa)) != 0)
+ goto out;
+ if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)
+ goto out;
break;
#endif /* WITH_OPENSSL */
case KEY_ED25519:
@@ -3029,7 +3072,6 @@
break;
case KEY_ED25519_CERT:
if ((r = sshkey_froms(buf, &k)) != 0 ||
- (r = sshkey_add_private(k)) != 0 ||
(r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
(r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
goto out;
@@ -3066,7 +3108,6 @@
break;
case KEY_XMSS_CERT:
if ((r = sshkey_froms(buf, &k)) != 0 ||
- (r = sshkey_add_private(k)) != 0 ||
(r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 ||
(r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 ||
(r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0)
@@ -3115,6 +3156,17 @@
free(curve);
#ifdef WITH_OPENSSL
BN_clear_free(exponent);
+ BN_clear_free(dsa_p);
+ BN_clear_free(dsa_q);
+ BN_clear_free(dsa_g);
+ BN_clear_free(dsa_pub_key);
+ BN_clear_free(dsa_priv_key);
+ BN_clear_free(rsa_n);
+ BN_clear_free(rsa_e);
+ BN_clear_free(rsa_d);
+ BN_clear_free(rsa_p);
+ BN_clear_free(rsa_q);
+ BN_clear_free(rsa_iqmp);
#endif /* WITH_OPENSSL */
sshkey_free(k);
freezero(ed25519_pk, pklen);
@@ -3769,7 +3821,9 @@
switch (pem_reason) {
case EVP_R_BAD_DECRYPT:
return SSH_ERR_KEY_WRONG_PASSPHRASE;
+#ifdef EVP_R_BN_DECODE_ERROR
case EVP_R_BN_DECODE_ERROR:
+#endif
case EVP_R_DECODE_ERROR:
#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
case EVP_R_PRIVATE_KEY_DECODE_ERROR:
@@ -3834,7 +3888,7 @@
r = convert_libcrypto_error();
goto out;
}
- if (pk->type == EVP_PKEY_RSA &&
+ if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA &&
(type == KEY_UNSPEC || type == KEY_RSA)) {
if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
@@ -3849,11 +3903,9 @@
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- if (BN_num_bits(prv->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
- r = SSH_ERR_KEY_LENGTH;
+ if ((r = check_rsa_length(prv->rsa)) != 0)
goto out;
- }
- } else if (pk->type == EVP_PKEY_DSA &&
+ } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA &&
(type == KEY_UNSPEC || type == KEY_DSA)) {
if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
@@ -3865,7 +3917,7 @@
DSA_print_fp(stderr, prv->dsa, 8);
#endif
#ifdef OPENSSL_HAS_ECC
- } else if (pk->type == EVP_PKEY_EC &&
+ } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_EC &&
(type == KEY_UNSPEC || type == KEY_ECDSA)) {
if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
Index: head/secure/lib/libssh/Makefile
===================================================================
--- head/secure/lib/libssh/Makefile
+++ head/secure/lib/libssh/Makefile
@@ -31,7 +31,9 @@
# Portability layer
SRCS+= bcrypt_pbkdf.c blowfish.c bsd-misc.c bsd-signal.c explicit_bzero.c \
- fmt_scaled.c freezero.c glob.c openssl-compat.c port-net.c \
+ fmt_scaled.c freezero.c glob.c \
+ libressl-api-compat.c \
+ openssl-compat.c port-net.c \
realpath.c recallocarray.c strtonum.c timingsafe_bcmp.c vis.c xcrypt.c
.if ${MK_LDNS} == "no"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 7, 3:55 PM (16 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30964512
Default Alt Text
D17444.id.diff (107 KB)
Attached To
Mode
D17444: openssh: cherry-pick OpenSSL 1.1.1 compatibility
Attached
Detach File
Event Timeline
Log In to Comment