1From 37e233307a79a9250962dcf77b7c7e27a02a1a35 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Fri, 1 Feb 2019 22:44:10 -0800
4Subject: [PATCH] Adapt to OpenSSL 1.1.1
5
6From: Guido Falsi <mad@madpilot.net>
7https://sources.debian.org/src/pam-ssh-agent-auth/0.10.3-3/debian/patches/openssl-1.1.1-1.patch/
8
9Upstream-Status: Pending
10Signed-off-by: Khem Raj <raj.khem@gmail.com>
11---
12 authfd.c    |  50 ++++++++++++++++++++
13 bufbn.c     |   4 ++
14 cipher.h    |   6 ++-
15 kex.h       |   9 +++-
16 key.c       | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++--
17 ssh-dss.c   |  51 ++++++++++++++++----
18 ssh-ecdsa.c |  40 ++++++++++++----
19 ssh-rsa.c   |  22 +++++++--
20 8 files changed, 287 insertions(+), 28 deletions(-)
21
22diff --git a/authfd.c b/authfd.c
23index 212e06b..f91514d 100644
24--- a/authfd.c
25+++ b/authfd.c
26@@ -367,6 +367,7 @@ ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int versio
27 	case 1:
28 		key = pamsshagentauth_key_new(KEY_RSA1);
29 		bits = pamsshagentauth_buffer_get_int(&auth->identities);
30+#if OPENSSL_VERSION_NUMBER < 0x10100000L
31 		pamsshagentauth_buffer_get_bignum(&auth->identities, key->rsa->e);
32 		pamsshagentauth_buffer_get_bignum(&auth->identities, key->rsa->n);
33 		*comment = pamsshagentauth_buffer_get_string(&auth->identities, NULL);
34@@ -374,6 +375,15 @@ ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int versio
35 		if (keybits < 0 || bits != (u_int)keybits)
36 			pamsshagentauth_logit("Warning: identity keysize mismatch: actual %d, announced %u",
37 			    BN_num_bits(key->rsa->n), bits);
38+#else
39+		pamsshagentauth_buffer_get_bignum(&auth->identities, RSA_get0_e(key->rsa));
40+		pamsshagentauth_buffer_get_bignum(&auth->identities, RSA_get0_n(key->rsa));
41+		*comment = pamsshagentauth_buffer_get_string(&auth->identities, NULL);
42+		keybits = BN_num_bits(RSA_get0_n(key->rsa));
43+		if (keybits < 0 || bits != (u_int)keybits)
44+			pamsshagentauth_logit("Warning: identity keysize mismatch: actual %d, announced %u",
45+			    BN_num_bits(RSA_get0_n(key->rsa)), bits);
46+#endif
47 		break;
48 	case 2:
49 		blob = pamsshagentauth_buffer_get_string(&auth->identities, &blen);
50@@ -417,9 +427,15 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
51 	}
52 	pamsshagentauth_buffer_init(&buffer);
53 	pamsshagentauth_buffer_put_char(&buffer, SSH_AGENTC_RSA_CHALLENGE);
54+#if OPENSSL_VERSION_NUMBER < 0x10100000L
55 	pamsshagentauth_buffer_put_int(&buffer, BN_num_bits(key->rsa->n));
56 	pamsshagentauth_buffer_put_bignum(&buffer, key->rsa->e);
57 	pamsshagentauth_buffer_put_bignum(&buffer, key->rsa->n);
58+#else
59+	pamsshagentauth_buffer_put_int(&buffer, BN_num_bits(RSA_get0_n(key->rsa)));
60+	pamsshagentauth_buffer_put_bignum(&buffer, RSA_get0_e(key->rsa));
61+	pamsshagentauth_buffer_put_bignum(&buffer, RSA_get0_n(key->rsa));
62+#endif
63 	pamsshagentauth_buffer_put_bignum(&buffer, challenge);
64 	pamsshagentauth_buffer_append(&buffer, session_id, 16);
65 	pamsshagentauth_buffer_put_int(&buffer, response_type);
66@@ -496,6 +512,7 @@ ssh_agent_sign(AuthenticationConnection *auth,
67 static void
68 ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment)
69 {
70+#if OPENSSL_VERSION_NUMBER < 0x10100000L
71 	pamsshagentauth_buffer_put_int(b, BN_num_bits(key->n));
72 	pamsshagentauth_buffer_put_bignum(b, key->n);
73 	pamsshagentauth_buffer_put_bignum(b, key->e);
74@@ -504,6 +521,16 @@ ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment)
75 	pamsshagentauth_buffer_put_bignum(b, key->iqmp);	/* ssh key->u */
76 	pamsshagentauth_buffer_put_bignum(b, key->q);	/* ssh key->p, SSL key->q */
77 	pamsshagentauth_buffer_put_bignum(b, key->p);	/* ssh key->q, SSL key->p */
78+#else
79+	pamsshagentauth_buffer_put_int(b, BN_num_bits(RSA_get0_n(key)));
80+	pamsshagentauth_buffer_put_bignum(b, RSA_get0_n(key));
81+	pamsshagentauth_buffer_put_bignum(b, RSA_get0_e(key));
82+	pamsshagentauth_buffer_put_bignum(b, RSA_get0_d(key));
83+	/* To keep within the protocol: p < q for ssh. in SSL p > q */
84+	pamsshagentauth_buffer_put_bignum(b, RSA_get0_iqmp(key));	/* ssh key->u */
85+	pamsshagentauth_buffer_put_bignum(b, RSA_get0_q(key));	/* ssh key->p, SSL key->q */
86+	pamsshagentauth_buffer_put_bignum(b, RSA_get0_p(key));	/* ssh key->q, SSL key->p */
87+#endif
88 	pamsshagentauth_buffer_put_cstring(b, comment);
89 }
90
91@@ -513,19 +540,36 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
92 	pamsshagentauth_buffer_put_cstring(b, key_ssh_name(key));
93 	switch (key->type) {
94 	case KEY_RSA:
95+#if OPENSSL_VERSION_NUMBER < 0x10100000L
96 		pamsshagentauth_buffer_put_bignum2(b, key->rsa->n);
97 		pamsshagentauth_buffer_put_bignum2(b, key->rsa->e);
98 		pamsshagentauth_buffer_put_bignum2(b, key->rsa->d);
99 		pamsshagentauth_buffer_put_bignum2(b, key->rsa->iqmp);
100 		pamsshagentauth_buffer_put_bignum2(b, key->rsa->p);
101 		pamsshagentauth_buffer_put_bignum2(b, key->rsa->q);
102+#else
103+		pamsshagentauth_buffer_put_bignum2(b, RSA_get0_n(key->rsa));
104+		pamsshagentauth_buffer_put_bignum2(b, RSA_get0_e(key->rsa));
105+		pamsshagentauth_buffer_put_bignum2(b, RSA_get0_d(key->rsa));
106+		pamsshagentauth_buffer_put_bignum2(b, RSA_get0_iqmp(key->rsa));
107+		pamsshagentauth_buffer_put_bignum2(b, RSA_get0_p(key->rsa));
108+		pamsshagentauth_buffer_put_bignum2(b, RSA_get0_q(key->rsa));
109+#endif
110 		break;
111 	case KEY_DSA:
112+#if OPENSSL_VERSION_NUMBER < 0x10100000L
113 		pamsshagentauth_buffer_put_bignum2(b, key->dsa->p);
114 		pamsshagentauth_buffer_put_bignum2(b, key->dsa->q);
115 		pamsshagentauth_buffer_put_bignum2(b, key->dsa->g);
116 		pamsshagentauth_buffer_put_bignum2(b, key->dsa->pub_key);
117 		pamsshagentauth_buffer_put_bignum2(b, key->dsa->priv_key);
118+#else
119+		pamsshagentauth_buffer_put_bignum2(b, DSA_get0_p(key->dsa));
120+		pamsshagentauth_buffer_put_bignum2(b, DSA_get0_q(key->dsa));
121+		pamsshagentauth_buffer_put_bignum2(b, DSA_get0_g(key->dsa));
122+		pamsshagentauth_buffer_put_bignum2(b, DSA_get0_pub_key(key->dsa));
123+		pamsshagentauth_buffer_put_bignum2(b, DSA_get0_priv_key(key->dsa));
124+#endif
125 		break;
126 	}
127 	pamsshagentauth_buffer_put_cstring(b, comment);
128@@ -605,9 +649,15 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key)
129
130 	if (key->type == KEY_RSA1) {
131 		pamsshagentauth_buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY);
132+#if OPENSSL_VERSION_NUMBER < 0x10100000L
133 		pamsshagentauth_buffer_put_int(&msg, BN_num_bits(key->rsa->n));
134 		pamsshagentauth_buffer_put_bignum(&msg, key->rsa->e);
135 		pamsshagentauth_buffer_put_bignum(&msg, key->rsa->n);
136+#else
137+		pamsshagentauth_buffer_put_int(&msg, BN_num_bits(RSA_get0_n(key->rsa)));
138+		pamsshagentauth_buffer_put_bignum(&msg, RSA_get0_e(key->rsa));
139+		pamsshagentauth_buffer_put_bignum(&msg, RSA_get0_n(key->rsa));
140+#endif
141 	} else if (key->type == KEY_DSA || key->type == KEY_RSA) {
142 		pamsshagentauth_key_to_blob(key, &blob, &blen);
143 		pamsshagentauth_buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
144diff --git a/bufbn.c b/bufbn.c
145index 6a49c73..4ecedc1 100644
146--- a/bufbn.c
147+++ b/bufbn.c
148@@ -151,7 +151,11 @@ pamsshagentauth_buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value)
149 		pamsshagentauth_buffer_put_int(buffer, 0);
150 		return 0;
151 	}
152+#if OPENSSL_VERSION_NUMBER < 0x10100000L
153 	if (value->neg) {
154+#else
155+	if (BN_is_negative(value)) {
156+#endif
157 		pamsshagentauth_logerror("buffer_put_bignum2_ret: negative numbers not supported");
158 		return (-1);
159 	}
160diff --git a/cipher.h b/cipher.h
161index 49bbc16..64f59ca 100644
162--- a/cipher.h
163+++ b/cipher.h
164@@ -59,15 +59,18 @@
165 #define CIPHER_DECRYPT		0
166
167 typedef struct Cipher Cipher;
168-typedef struct CipherContext CipherContext;
169+// typedef struct CipherContext CipherContext;
170
171 struct Cipher;
172+/*
173 struct CipherContext {
174 	int	plaintext;
175 	EVP_CIPHER_CTX evp;
176 	Cipher *cipher;
177 };
178+*/
179
180+/*
181 u_int	 cipher_mask_ssh1(int);
182 Cipher	*cipher_by_name(const char *);
183 Cipher	*cipher_by_number(int);
184@@ -88,4 +91,5 @@ void	 cipher_set_keyiv(CipherContext *, u_char *);
185 int	 cipher_get_keyiv_len(const CipherContext *);
186 int	 cipher_get_keycontext(const CipherContext *, u_char *);
187 void	 cipher_set_keycontext(CipherContext *, u_char *);
188+*/
189 #endif				/* CIPHER_H */
190diff --git a/kex.h b/kex.h
191index 8e29c90..81ca57d 100644
192--- a/kex.h
193+++ b/kex.h
194@@ -70,7 +70,7 @@ enum kex_exchange {
195 #define KEX_INIT_SENT	0x0001
196
197 typedef struct Kex Kex;
198-typedef struct Mac Mac;
199+// typedef struct Mac Mac;
200 typedef struct Comp Comp;
201 typedef struct Enc Enc;
202 typedef struct Newkeys Newkeys;
203@@ -84,6 +84,7 @@ struct Enc {
204 	u_char	*key;
205 	u_char	*iv;
206 };
207+/*
208 struct Mac {
209 	char	*name;
210 	int	enabled;
211@@ -95,11 +96,13 @@ struct Mac {
212 	HMAC_CTX	evp_ctx;
213 	struct umac_ctx *umac_ctx;
214 };
215+*/
216 struct Comp {
217 	int	type;
218 	int	enabled;
219 	char	*name;
220 };
221+/*
222 struct Newkeys {
223 	Enc	enc;
224 	Mac	mac;
225@@ -126,7 +129,9 @@ struct Kex {
226 	int	(*host_key_index)(Key *);
227 	void	(*kex[KEX_MAX])(Kex *);
228 };
229+*/
230
231+/*
232 Kex	*kex_setup(char *[PROPOSAL_MAX]);
233 void	 kex_finish(Kex *);
234
235@@ -152,6 +157,8 @@ kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *,
236 void
237 derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);
238
239+*/
240+
241 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)
242 void	dump_digest(char *, u_char *, int);
243 #endif
244diff --git a/key.c b/key.c
245index 107a442..aedbbb5 100644
246--- a/key.c
247+++ b/key.c
248@@ -77,15 +77,21 @@ pamsshagentauth_key_new(int type)
249 	case KEY_RSA:
250 		if ((rsa = RSA_new()) == NULL)
251 			pamsshagentauth_fatal("key_new: RSA_new failed");
252+#if OPENSSL_VERSION_NUMBER < 0x10100000L
253 		if ((rsa->n = BN_new()) == NULL)
254 			pamsshagentauth_fatal("key_new: BN_new failed");
255 		if ((rsa->e = BN_new()) == NULL)
256 			pamsshagentauth_fatal("key_new: BN_new failed");
257+#else
258+		if (RSA_set0_key(rsa, BN_new(), BN_new(), NULL) != 1)
259+			pamsshagentauth_fatal("key_new: RSA_set0_key failed");
260+#endif
261 		k->rsa = rsa;
262 		break;
263 	case KEY_DSA:
264 		if ((dsa = DSA_new()) == NULL)
265 			pamsshagentauth_fatal("key_new: DSA_new failed");
266+#if OPENSSL_VERSION_NUMBER < 0x10100000L
267 		if ((dsa->p = BN_new()) == NULL)
268 			pamsshagentauth_fatal("key_new: BN_new failed");
269 		if ((dsa->q = BN_new()) == NULL)
270@@ -94,6 +100,12 @@ pamsshagentauth_key_new(int type)
271 			pamsshagentauth_fatal("key_new: BN_new failed");
272 		if ((dsa->pub_key = BN_new()) == NULL)
273 			pamsshagentauth_fatal("key_new: BN_new failed");
274+#else
275+		if (DSA_set0_pqg(dsa, BN_new(), BN_new(), BN_new()) != 1)
276+			pamsshagentauth_fatal("key_new: DSA_set0_pqg failed");
277+		if (DSA_set0_key(dsa, BN_new(), NULL) != 1)
278+			pamsshagentauth_fatal("key_new: DSA_set0_key failed");
279+#endif
280 		k->dsa = dsa;
281 		break;
282 	case KEY_ECDSA:
283@@ -118,6 +130,7 @@ pamsshagentauth_key_new_private(int type)
284 	switch (k->type) {
285 	case KEY_RSA1:
286 	case KEY_RSA:
287+#if OPENSSL_VERSION_NUMBER < 0x10100000L
288 		if ((k->rsa->d = BN_new()) == NULL)
289 			pamsshagentauth_fatal("key_new_private: BN_new failed");
290 		if ((k->rsa->iqmp = BN_new()) == NULL)
291@@ -130,14 +143,30 @@ pamsshagentauth_key_new_private(int type)
292 			pamsshagentauth_fatal("key_new_private: BN_new failed");
293 		if ((k->rsa->dmp1 = BN_new()) == NULL)
294 			pamsshagentauth_fatal("key_new_private: BN_new failed");
295+#else
296+		if (RSA_set0_key(k->rsa, NULL, NULL, BN_new()) != 1)
297+			pamsshagentauth_fatal("key_new: RSA_set0_key failed");
298+		if (RSA_set0_crt_params(k->rsa, BN_new(), BN_new(), BN_new()) != 1)
299+			pamsshagentauth_fatal("key_new: RSA_set0_crt_params failed");
300+		if (RSA_set0_factors(k->rsa, BN_new(), BN_new()) != 1)
301+			pamsshagentauth_fatal("key_new: RSA_set0_factors failed");
302+#endif
303 		break;
304 	case KEY_DSA:
305+#if OPENSSL_VERSION_NUMBER < 0x10100000L
306 		if ((k->dsa->priv_key = BN_new()) == NULL)
307 			pamsshagentauth_fatal("key_new_private: BN_new failed");
308+#else
309+		if (DSA_set0_key(k->dsa, NULL, BN_new()) != 1)
310+			pamsshagentauth_fatal("key_new_private: DSA_set0_key failed");
311+#endif
312 		break;
313 	case KEY_ECDSA:
314+#if OPENSSL_VERSION_NUMBER < 0x10100000L
315 		if (EC_KEY_set_private_key(k->ecdsa, BN_new()) != 1)
316 			pamsshagentauth_fatal("key_new_private: EC_KEY_set_private_key failed");
317+#else
318+#endif
319 		break;
320 	case KEY_ED25519:
321 		RAND_bytes(k->ed25519->sk, sizeof(k->ed25519->sk));
322@@ -195,14 +224,26 @@ pamsshagentauth_key_equal(const Key *a, const Key *b)
323 	case KEY_RSA1:
324 	case KEY_RSA:
325 		return a->rsa != NULL && b->rsa != NULL &&
326+#if OPENSSL_VERSION_NUMBER < 0x10100000L
327 		    BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
328 		    BN_cmp(a->rsa->n, b->rsa->n) == 0;
329+#else
330+		    BN_cmp(RSA_get0_e(a->rsa), RSA_get0_e(b->rsa)) == 0 &&
331+		    BN_cmp(RSA_get0_n(a->rsa), RSA_get0_n(b->rsa)) == 0;
332+#endif
333 	case KEY_DSA:
334 		return a->dsa != NULL && b->dsa != NULL &&
335+#if OPENSSL_VERSION_NUMBER < 0x10100000L
336 		    BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
337 		    BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
338 		    BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
339 		    BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
340+#else
341+		    BN_cmp(DSA_get0_p(a->dsa), DSA_get0_p(b->dsa)) == 0 &&
342+		    BN_cmp(DSA_get0_q(a->dsa), DSA_get0_q(b->dsa)) == 0 &&
343+		    BN_cmp(DSA_get0_g(a->dsa), DSA_get0_g(b->dsa)) == 0 &&
344+		    BN_cmp(DSA_get0_pub_key(a->dsa), DSA_get0_pub_key(b->dsa)) == 0;
345+#endif
346 	case KEY_ECDSA:
347 		return a->ecdsa != NULL && b->ecdsa != NULL &&
348 			EC_KEY_check_key(a->ecdsa) == 1 &&
349@@ -231,7 +272,7 @@ pamsshagentauth_key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
350     u_int *dgst_raw_length)
351 {
352 	const EVP_MD *md = NULL;
353-	EVP_MD_CTX ctx;
354+	EVP_MD_CTX *ctx;
355 	u_char *blob = NULL;
356 	u_char *retval = NULL;
357 	u_int len = 0;
358@@ -252,12 +293,21 @@ pamsshagentauth_key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
359 	}
360 	switch (k->type) {
361 	case KEY_RSA1:
362+#if OPENSSL_VERSION_NUMBER < 0x10100000L
363 		nlen = BN_num_bytes(k->rsa->n);
364 		elen = BN_num_bytes(k->rsa->e);
365 		len = nlen + elen;
366 		blob = pamsshagentauth_xmalloc(len);
367 		BN_bn2bin(k->rsa->n, blob);
368 		BN_bn2bin(k->rsa->e, blob + nlen);
369+#else
370+		nlen = BN_num_bytes(RSA_get0_n(k->rsa));
371+		elen = BN_num_bytes(RSA_get0_e(k->rsa));
372+		len = nlen + elen;
373+		blob = pamsshagentauth_xmalloc(len);
374+		BN_bn2bin(RSA_get0_n(k->rsa), blob);
375+		BN_bn2bin(RSA_get0_e(k->rsa), blob + nlen);
376+#endif
377 		break;
378 	case KEY_DSA:
379 	case KEY_ECDSA:
380@@ -273,11 +323,14 @@ pamsshagentauth_key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
381 	}
382 	if (blob != NULL) {
383 		retval = pamsshagentauth_xmalloc(EVP_MAX_MD_SIZE);
384-		EVP_DigestInit(&ctx, md);
385-		EVP_DigestUpdate(&ctx, blob, len);
386-		EVP_DigestFinal(&ctx, retval, dgst_raw_length);
387+		/* XXX Errors from EVP_* functions are not hadled */
388+		ctx = EVP_MD_CTX_create();
389+		EVP_DigestInit(ctx, md);
390+		EVP_DigestUpdate(ctx, blob, len);
391+		EVP_DigestFinal(ctx, retval, dgst_raw_length);
392 		memset(blob, 0, len);
393 		pamsshagentauth_xfree(blob);
394+		EVP_MD_CTX_destroy(ctx);
395 	} else {
396 		pamsshagentauth_fatal("key_fingerprint_raw: blob is null");
397 	}
398@@ -457,10 +510,17 @@ pamsshagentauth_key_read(Key *ret, char **cpp)
399 			return -1;
400 		*cpp = cp;
401 		/* Get public exponent, public modulus. */
402+#if OPENSSL_VERSION_NUMBER < 0x10100000L
403 		if (!read_bignum(cpp, ret->rsa->e))
404 			return -1;
405 		if (!read_bignum(cpp, ret->rsa->n))
406 			return -1;
407+#else
408+		if (!read_bignum(cpp, RSA_get0_e(ret->rsa)))
409+			return -1;
410+		if (!read_bignum(cpp, RSA_get0_n(ret->rsa)))
411+			return -1;
412+#endif
413 		success = 1;
414 		break;
415 	case KEY_UNSPEC:
416@@ -583,10 +643,17 @@ pamsshagentauth_key_write(const Key *key, FILE *f)
417
418 	if (key->type == KEY_RSA1 && key->rsa != NULL) {
419 		/* size of modulus 'n' */
420+#if OPENSSL_VERSION_NUMBER < 0x10100000L
421 		bits = BN_num_bits(key->rsa->n);
422 		fprintf(f, "%u", bits);
423 		if (write_bignum(f, key->rsa->e) &&
424 		    write_bignum(f, key->rsa->n)) {
425+#else
426+		bits = BN_num_bits(RSA_get0_n(key->rsa));
427+		fprintf(f, "%u", bits);
428+		if (write_bignum(f, RSA_get0_e(key->rsa)) &&
429+		    write_bignum(f, RSA_get0_n(key->rsa))) {
430+#endif
431 			success = 1;
432 		} else {
433 			pamsshagentauth_logerror("key_write: failed for RSA key");
434@@ -675,10 +742,17 @@ pamsshagentauth_key_size(const Key *k)
435 {
436 	switch (k->type) {
437 	case KEY_RSA1:
438+#if OPENSSL_VERSION_NUMBER < 0x10100000L
439 	case KEY_RSA:
440 		return BN_num_bits(k->rsa->n);
441 	case KEY_DSA:
442 		return BN_num_bits(k->dsa->p);
443+#else
444+	case KEY_RSA:
445+		return BN_num_bits(RSA_get0_n(k->rsa));
446+	case KEY_DSA:
447+		return BN_num_bits(DSA_get0_p(k->dsa));
448+#endif
449 	case KEY_ECDSA:
450 	{
451 		int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(k->ecdsa));
452@@ -769,17 +843,29 @@ pamsshagentauth_key_from_private(const Key *k)
453 	switch (k->type) {
454 	case KEY_DSA:
455 		n = pamsshagentauth_key_new(k->type);
456+#if OPENSSL_VERSION_NUMBER < 0x10100000L
457 		if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
458 		    (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
459 		    (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||
460 		    (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL))
461+#else
462+		if ((BN_copy(DSA_get0_p(n->dsa), DSA_get0_p(k->dsa)) == NULL) ||
463+		    (BN_copy(DSA_get0_q(n->dsa), DSA_get0_q(k->dsa)) == NULL) ||
464+		    (BN_copy(DSA_get0_g(n->dsa), DSA_get0_g(k->dsa)) == NULL) ||
465+		    (BN_copy(DSA_get0_pub_key(n->dsa), DSA_get0_pub_key(k->dsa)) == NULL))
466+#endif
467 			pamsshagentauth_fatal("key_from_private: BN_copy failed");
468 		break;
469 	case KEY_RSA:
470 	case KEY_RSA1:
471 		n = pamsshagentauth_key_new(k->type);
472+#if OPENSSL_VERSION_NUMBER < 0x10100000L
473 		if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
474 		    (BN_copy(n->rsa->e, k->rsa->e) == NULL))
475+#else
476+		if ((BN_copy(RSA_get0_n(n->rsa), RSA_get0_n(k->rsa)) == NULL) ||
477+		    (BN_copy(RSA_get0_e(n->rsa), RSA_get0_e(k->rsa)) == NULL))
478+#endif
479 			pamsshagentauth_fatal("key_from_private: BN_copy failed");
480 		break;
481 	case KEY_ECDSA:
482@@ -881,8 +967,13 @@ pamsshagentauth_key_from_blob(const u_char *blob, u_int blen)
483 	switch (type) {
484 	case KEY_RSA:
485 		key = pamsshagentauth_key_new(type);
486+#if OPENSSL_VERSION_NUMBER < 0x10100000L
487 		if (pamsshagentauth_buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
488 		    pamsshagentauth_buffer_get_bignum2_ret(&b, key->rsa->n) == -1) {
489+#else
490+		if (pamsshagentauth_buffer_get_bignum2_ret(&b, RSA_get0_e(key->rsa)) == -1 ||
491+		    pamsshagentauth_buffer_get_bignum2_ret(&b, RSA_get0_n(key->rsa)) == -1) {
492+#endif
493 			pamsshagentauth_logerror("key_from_blob: can't read rsa key");
494 			pamsshagentauth_key_free(key);
495 			key = NULL;
496@@ -894,10 +985,17 @@ pamsshagentauth_key_from_blob(const u_char *blob, u_int blen)
497 		break;
498 	case KEY_DSA:
499 		key = pamsshagentauth_key_new(type);
500+#if OPENSSL_VERSION_NUMBER < 0x10100000L
501 		if (pamsshagentauth_buffer_get_bignum2_ret(&b, key->dsa->p) == -1 ||
502 		    pamsshagentauth_buffer_get_bignum2_ret(&b, key->dsa->q) == -1 ||
503 		    pamsshagentauth_buffer_get_bignum2_ret(&b, key->dsa->g) == -1 ||
504 		    pamsshagentauth_buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) {
505+#else
506+		if (pamsshagentauth_buffer_get_bignum2_ret(&b, DSA_get0_p(key->dsa)) == -1 ||
507+		    pamsshagentauth_buffer_get_bignum2_ret(&b, DSA_get0_q(key->dsa)) == -1 ||
508+		    pamsshagentauth_buffer_get_bignum2_ret(&b, DSA_get0_g(key->dsa)) == -1 ||
509+		    pamsshagentauth_buffer_get_bignum2_ret(&b, DSA_get0_pub_key(key->dsa)) == -1) {
510+#endif
511 			pamsshagentauth_logerror("key_from_blob: can't read dsa key");
512 			pamsshagentauth_key_free(key);
513 			key = NULL;
514@@ -1015,6 +1113,7 @@ pamsshagentauth_key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
515 	}
516 	pamsshagentauth_buffer_init(&b);
517 	switch (key->type) {
518+#if OPENSSL_VERSION_NUMBER < 0x10100000L
519 	case KEY_DSA:
520 		pamsshagentauth_buffer_put_cstring(&b, key_ssh_name(key));
521 		pamsshagentauth_buffer_put_bignum2(&b, key->dsa->p);
522@@ -1027,6 +1126,20 @@ pamsshagentauth_key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
523 		pamsshagentauth_buffer_put_bignum2(&b, key->rsa->e);
524 		pamsshagentauth_buffer_put_bignum2(&b, key->rsa->n);
525 		break;
526+#else
527+	case KEY_DSA:
528+		pamsshagentauth_buffer_put_cstring(&b, key_ssh_name(key));
529+		pamsshagentauth_buffer_put_bignum2(&b, DSA_get0_p(key->dsa));
530+		pamsshagentauth_buffer_put_bignum2(&b, DSA_get0_q(key->dsa));
531+		pamsshagentauth_buffer_put_bignum2(&b, DSA_get0_g(key->dsa));
532+		pamsshagentauth_buffer_put_bignum2(&b, DSA_get0_pub_key(key->dsa));
533+		break;
534+	case KEY_RSA:
535+		pamsshagentauth_buffer_put_cstring(&b, key_ssh_name(key));
536+		pamsshagentauth_buffer_put_bignum2(&b, RSA_get0_e(key->rsa));
537+		pamsshagentauth_buffer_put_bignum2(&b, RSA_get0_n(key->rsa));
538+		break;
539+#endif
540 	case KEY_ECDSA:
541 	{
542 		size_t l = 0;
543@@ -1138,14 +1251,20 @@ pamsshagentauth_key_demote(const Key *k)
544 	case KEY_RSA:
545 		if ((pk->rsa = RSA_new()) == NULL)
546 			pamsshagentauth_fatal("key_demote: RSA_new failed");
547+#if OPENSSL_VERSION_NUMBER < 0x10100000L
548 		if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL)
549 			pamsshagentauth_fatal("key_demote: BN_dup failed");
550 		if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL)
551 			pamsshagentauth_fatal("key_demote: BN_dup failed");
552+#else
553+		if (RSA_set0_key(pk->rsa, BN_dup(RSA_get0_n(k->rsa)), BN_dup(RSA_get0_e(k->rsa)), NULL) != 1)
554+			pamsshagentauth_fatal("key_demote: RSA_set0_key failed");
555+#endif
556 		break;
557 	case KEY_DSA:
558 		if ((pk->dsa = DSA_new()) == NULL)
559 			pamsshagentauth_fatal("key_demote: DSA_new failed");
560+#if OPENSSL_VERSION_NUMBER < 0x10100000L
561 		if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL)
562 			pamsshagentauth_fatal("key_demote: BN_dup failed");
563 		if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL)
564@@ -1154,6 +1273,12 @@ pamsshagentauth_key_demote(const Key *k)
565 			pamsshagentauth_fatal("key_demote: BN_dup failed");
566 		if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL)
567 			pamsshagentauth_fatal("key_demote: BN_dup failed");
568+#else
569+		if (DSA_set0_pqg(pk->dsa, BN_dup(DSA_get0_p(k->dsa)), BN_dup(DSA_get0_q(k->dsa)), BN_dup(DSA_get0_g(k->dsa))) != 1)
570+			pamsshagentauth_fatal("key_demote: DSA_set0_pqg failed");
571+		if (DSA_set0_key(pk->dsa, BN_dup(DSA_get0_pub_key(k->dsa)), NULL) != 1)
572+			pamsshagentauth_fatal("key_demote: DSA_set0_key failed");
573+#endif
574 		break;
575 	case KEY_ECDSA:
576 		pamsshagentauth_fatal("key_demote: implement me");
577diff --git a/ssh-dss.c b/ssh-dss.c
578index 9fdaa5d..1051ae2 100644
579--- a/ssh-dss.c
580+++ b/ssh-dss.c
581@@ -48,37 +48,53 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
582 {
583 	DSA_SIG *sig;
584 	const EVP_MD *evp_md = EVP_sha1();
585-	EVP_MD_CTX md;
586+	EVP_MD_CTX *md;
587 	u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
588 	u_int rlen, slen, len, dlen;
589 	Buffer b;
590+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
591+	const BIGNUM *r, *s;
592+#endif
593
594 	if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
595 		pamsshagentauth_logerror("ssh_dss_sign: no DSA key");
596 		return -1;
597 	}
598-	EVP_DigestInit(&md, evp_md);
599-	EVP_DigestUpdate(&md, data, datalen);
600-	EVP_DigestFinal(&md, digest, &dlen);
601+	md = EVP_MD_CTX_create();
602+	EVP_DigestInit(md, evp_md);
603+	EVP_DigestUpdate(md, data, datalen);
604+	EVP_DigestFinal(md, digest, &dlen);
605
606 	sig = DSA_do_sign(digest, dlen, key->dsa);
607 	memset(digest, 'd', sizeof(digest));
608+	EVP_MD_CTX_destroy(md);
609
610 	if (sig == NULL) {
611 		pamsshagentauth_logerror("ssh_dss_sign: sign failed");
612 		return -1;
613 	}
614
615+#if OPENSSL_VERSION_NUMBER < 0x10100000L
616 	rlen = BN_num_bytes(sig->r);
617 	slen = BN_num_bytes(sig->s);
618+#else
619+	DSA_SIG_get0((const DSA_SIG *)sig, (const BIGNUM **)r, (const BIGNUM **)s);
620+	rlen = BN_num_bytes(r);
621+	slen = BN_num_bytes(s);
622+#endif
623 	if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
624 		pamsshagentauth_logerror("bad sig size %u %u", rlen, slen);
625 		DSA_SIG_free(sig);
626 		return -1;
627 	}
628 	memset(sigblob, 0, SIGBLOB_LEN);
629+#if OPENSSL_VERSION_NUMBER < 0x10100000L
630 	BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
631 	BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
632+#else
633+	BN_bn2bin(r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
634+	BN_bn2bin(s, sigblob+ SIGBLOB_LEN - slen);
635+#endif
636 	DSA_SIG_free(sig);
637
638 	if (datafellows & SSH_BUG_SIGBLOB) {
639@@ -110,11 +126,14 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
640 {
641 	DSA_SIG *sig;
642 	const EVP_MD *evp_md = EVP_sha1();
643-	EVP_MD_CTX md;
644+	EVP_MD_CTX *md;
645 	u_char digest[EVP_MAX_MD_SIZE], *sigblob;
646 	u_int len, dlen;
647 	int rlen, ret;
648 	Buffer b;
649+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
650+	BIGNUM *r, *s;
651+#endif
652
653 	if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
654 		pamsshagentauth_logerror("ssh_dss_verify: no DSA key");
655@@ -157,6 +176,7 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
656 	/* parse signature */
657 	if ((sig = DSA_SIG_new()) == NULL)
658 		pamsshagentauth_fatal("ssh_dss_verify: DSA_SIG_new failed");
659+#if OPENSSL_VERSION_NUMBER < 0x10100000L
660 	if ((sig->r = BN_new()) == NULL)
661 		pamsshagentauth_fatal("ssh_dss_verify: BN_new failed");
662 	if ((sig->s = BN_new()) == NULL)
663@@ -164,18 +184,33 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
664 	if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) ||
665 	    (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL))
666 		pamsshagentauth_fatal("ssh_dss_verify: BN_bin2bn failed");
667+#else
668+	if ((r = BN_new()) == NULL)
669+		pamsshagentauth_fatal("ssh_dss_verify: BN_new failed");
670+	if ((s = BN_new()) == NULL)
671+		pamsshagentauth_fatal("ssh_dss_verify: BN_new failed");
672+	if (DSA_SIG_set0(sig, r, s) != 1)
673+		pamsshagentauth_fatal("ssh_dss_verify: DSA_SIG_set0 failed");
674+	if ((BN_bin2bn(sigblob, INTBLOB_LEN, r) == NULL) ||
675+	    (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, s) == NULL))
676+		pamsshagentauth_fatal("ssh_dss_verify: BN_bin2bn failed");
677+	if (DSA_SIG_set0(sig, r, s) != 1)
678+		pamsshagentauth_fatal("ssh_dss_verify: DSA_SIG_set0 failed");
679+#endif
680
681 	/* clean up */
682 	memset(sigblob, 0, len);
683 	pamsshagentauth_xfree(sigblob);
684
685 	/* sha1 the data */
686-	EVP_DigestInit(&md, evp_md);
687-	EVP_DigestUpdate(&md, data, datalen);
688-	EVP_DigestFinal(&md, digest, &dlen);
689+	md = EVP_MD_CTX_create();
690+	EVP_DigestInit(md, evp_md);
691+	EVP_DigestUpdate(md, data, datalen);
692+	EVP_DigestFinal(md, digest, &dlen);
693
694 	ret = DSA_do_verify(digest, dlen, sig, key->dsa);
695 	memset(digest, 'd', sizeof(digest));
696+	EVP_MD_CTX_destroy(md);
697
698 	DSA_SIG_free(sig);
699
700diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
701index efa0f3d..c213959 100644
702--- a/ssh-ecdsa.c
703+++ b/ssh-ecdsa.c
704@@ -41,22 +41,27 @@ ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp,
705 {
706     ECDSA_SIG *sig;
707     const EVP_MD *evp_md = evp_from_key(key);
708-    EVP_MD_CTX md;
709+    EVP_MD_CTX *md;
710     u_char digest[EVP_MAX_MD_SIZE];
711     u_int len, dlen;
712     Buffer b, bb;
713+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
714+	BIGNUM *r, *s;
715+#endif
716
717     if (key == NULL || key->type != KEY_ECDSA || key->ecdsa == NULL) {
718         pamsshagentauth_logerror("ssh_ecdsa_sign: no ECDSA key");
719         return -1;
720     }
721
722-    EVP_DigestInit(&md, evp_md);
723-    EVP_DigestUpdate(&md, data, datalen);
724-    EVP_DigestFinal(&md, digest, &dlen);
725+    md = EVP_MD_CTX_create();
726+    EVP_DigestInit(md, evp_md);
727+    EVP_DigestUpdate(md, data, datalen);
728+    EVP_DigestFinal(md, digest, &dlen);
729
730     sig = ECDSA_do_sign(digest, dlen, key->ecdsa);
731     memset(digest, 'd', sizeof(digest));
732+    EVP_MD_CTX_destroy(md);
733
734     if (sig == NULL) {
735         pamsshagentauth_logerror("ssh_ecdsa_sign: sign failed");
736@@ -64,8 +69,14 @@ ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp,
737     }
738
739     pamsshagentauth_buffer_init(&bb);
740+#if OPENSSL_VERSION_NUMBER < 0x10100000L
741     if (pamsshagentauth_buffer_get_bignum2_ret(&bb, sig->r) == -1 ||
742         pamsshagentauth_buffer_get_bignum2_ret(&bb, sig->s) == -1) {
743+#else
744+    DSA_SIG_get0(sig, &r, &s);
745+    if (pamsshagentauth_buffer_get_bignum2_ret(&bb, r) == -1 ||
746+        pamsshagentauth_buffer_get_bignum2_ret(&bb, s) == -1) {
747+#endif
748         pamsshagentauth_logerror("couldn't serialize signature");
749         ECDSA_SIG_free(sig);
750         return -1;
751@@ -94,11 +105,14 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
752 {
753     ECDSA_SIG *sig;
754     const EVP_MD *evp_md = evp_from_key(key);
755-    EVP_MD_CTX md;
756+    EVP_MD_CTX *md;
757     u_char digest[EVP_MAX_MD_SIZE], *sigblob;
758     u_int len, dlen;
759     int rlen, ret;
760     Buffer b;
761+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
762+	BIGNUM *r, *s;
763+#endif
764
765     if (key == NULL || key->type != KEY_ECDSA || key->ecdsa == NULL) {
766         pamsshagentauth_logerror("ssh_ecdsa_sign: no ECDSA key");
767@@ -127,8 +141,14 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
768
769     pamsshagentauth_buffer_init(&b);
770     pamsshagentauth_buffer_append(&b, sigblob, len);
771+#if OPENSSL_VERSION_NUMBER < 0x10100000L
772     if ((pamsshagentauth_buffer_get_bignum2_ret(&b, sig->r) == -1) ||
773         (pamsshagentauth_buffer_get_bignum2_ret(&b, sig->s) == -1))
774+#else
775+    DSA_SIG_get0(sig, &r, &s);
776+    if ((pamsshagentauth_buffer_get_bignum2_ret(&b, r) == -1) ||
777+        (pamsshagentauth_buffer_get_bignum2_ret(&b, s) == -1))
778+#endif
779         pamsshagentauth_fatal("ssh_ecdsa_verify:"
780             "pamsshagentauth_buffer_get_bignum2_ret failed");
781
782@@ -137,16 +157,18 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
783     pamsshagentauth_xfree(sigblob);
784
785     /* sha256 the data */
786-    EVP_DigestInit(&md, evp_md);
787-    EVP_DigestUpdate(&md, data, datalen);
788-    EVP_DigestFinal(&md, digest, &dlen);
789+    md = EVP_MD_CTX_create();
790+    EVP_DigestInit(md, evp_md);
791+    EVP_DigestUpdate(md, data, datalen);
792+    EVP_DigestFinal(md, digest, &dlen);
793
794     ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa);
795     memset(digest, 'd', sizeof(digest));
796+    EVP_MD_CTX_destroy(md);
797
798     ECDSA_SIG_free(sig);
799
800     pamsshagentauth_verbose("ssh_ecdsa_verify: signature %s",
801         ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
802     return ret;
803-}
804\ No newline at end of file
805+}
806diff --git a/ssh-rsa.c b/ssh-rsa.c
807index d05844b..9d74eb6 100644
808--- a/ssh-rsa.c
809+++ b/ssh-rsa.c
810@@ -40,7 +40,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
811     const u_char *data, u_int datalen)
812 {
813 	const EVP_MD *evp_md;
814-	EVP_MD_CTX md;
815+	EVP_MD_CTX *md;
816 	u_char digest[EVP_MAX_MD_SIZE], *sig;
817 	u_int slen, dlen, len;
818 	int ok, nid;
819@@ -55,6 +55,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
820 		pamsshagentauth_logerror("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid);
821 		return -1;
822 	}
823+	md = EVP_MD_CTX_create();
824 	EVP_DigestInit(&md, evp_md);
825 	EVP_DigestUpdate(&md, data, datalen);
826 	EVP_DigestFinal(&md, digest, &dlen);
827@@ -64,6 +65,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
828
829 	ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa);
830 	memset(digest, 'd', sizeof(digest));
831+	EVP_MD_CTX_destroy(md);
832
833 	if (ok != 1) {
834 		int ecode = ERR_get_error();
835@@ -107,7 +109,7 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
836 {
837 	Buffer b;
838 	const EVP_MD *evp_md;
839-	EVP_MD_CTX md;
840+	EVP_MD_CTX *md;
841 	char *ktype;
842 	u_char digest[EVP_MAX_MD_SIZE], *sigblob;
843 	u_int len, dlen, modlen;
844@@ -117,9 +119,17 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
845 		pamsshagentauth_logerror("ssh_rsa_verify: no RSA key");
846 		return -1;
847 	}
848+#if OPENSSL_VERSION_NUMBER < 0x10100000L
849 	if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
850+#else
851+	if (BN_num_bits(RSA_get0_n(key->rsa)) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
852+#endif
853 		pamsshagentauth_logerror("ssh_rsa_verify: RSA modulus too small: %d < minimum %d bits",
854+#if OPENSSL_VERSION_NUMBER < 0x10100000L
855 		    BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
856+#else
857+		    BN_num_bits(RSA_get0_n(key->rsa)), SSH_RSA_MINIMUM_MODULUS_SIZE);
858+#endif
859 		return -1;
860 	}
861 	pamsshagentauth_buffer_init(&b);
862@@ -161,12 +171,14 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
863 		pamsshagentauth_xfree(sigblob);
864 		return -1;
865 	}
866-	EVP_DigestInit(&md, evp_md);
867-	EVP_DigestUpdate(&md, data, datalen);
868-	EVP_DigestFinal(&md, digest, &dlen);
869+	md = EVP_MD_CTX_create();
870+	EVP_DigestInit(md, evp_md);
871+	EVP_DigestUpdate(md, data, datalen);
872+	EVP_DigestFinal(md, digest, &dlen);
873
874 	ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key->rsa);
875 	memset(digest, 'd', sizeof(digest));
876+	EVP_MD_CTX_destroy(md);
877 	memset(sigblob, 's', len);
878 	pamsshagentauth_xfree(sigblob);
879 	pamsshagentauth_verbose("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
880