Annotation of src/usr.bin/ssh/ssh-rsa.c, Revision 1.71
1.71 ! djm 1: /* $OpenBSD: ssh-rsa.c,v 1.70 2022/10/28 00:36:31 djm Exp $ */
1.1 markus 2: /*
1.30 markus 3: * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
1.1 markus 4: *
1.30 markus 5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
1.1 markus 8: *
1.30 markus 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1 markus 16: */
1.39 deraadt 17:
18: #include <sys/types.h>
1.5 markus 19:
20: #include <openssl/evp.h>
21: #include <openssl/err.h>
1.38 stevesk 22:
23: #include <string.h>
1.1 markus 24:
1.52 djm 25: #include "sshbuf.h"
1.8 markus 26: #include "compat.h"
1.52 djm 27: #include "ssherr.h"
28: #define SSHKEY_INTERNAL
29: #include "sshkey.h"
1.50 djm 30: #include "digest.h"
1.64 djm 31: #include "log.h"
1.1 markus 32:
1.52 djm 33: static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
1.25 markus 34:
1.69 djm 35: static u_int
36: ssh_rsa_size(const struct sshkey *key)
37: {
38: const BIGNUM *rsa_n;
39:
40: if (key->rsa == NULL)
41: return 0;
42: RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
43: return BN_num_bits(rsa_n);
44: }
45:
46: static int
47: ssh_rsa_alloc(struct sshkey *k)
48: {
49: if ((k->rsa = RSA_new()) == NULL)
50: return SSH_ERR_ALLOC_FAIL;
51: return 0;
52: }
53:
54: static void
55: ssh_rsa_cleanup(struct sshkey *k)
56: {
57: RSA_free(k->rsa);
58: k->rsa = NULL;
59: }
60:
1.70 djm 61: static int
62: ssh_rsa_equal(const struct sshkey *a, const struct sshkey *b)
63: {
64: const BIGNUM *rsa_e_a, *rsa_n_a;
65: const BIGNUM *rsa_e_b, *rsa_n_b;
66:
67: if (a->rsa == NULL || b->rsa == NULL)
68: return 0;
69: RSA_get0_key(a->rsa, &rsa_n_a, &rsa_e_a, NULL);
70: RSA_get0_key(b->rsa, &rsa_n_b, &rsa_e_b, NULL);
71: if (rsa_e_a == NULL || rsa_e_b == NULL)
72: return 0;
73: if (rsa_n_a == NULL || rsa_n_b == NULL)
74: return 0;
75: if (BN_cmp(rsa_e_a, rsa_e_b) != 0)
76: return 0;
77: if (BN_cmp(rsa_n_a, rsa_n_b) != 0)
78: return 0;
79: return 1;
80: }
81:
1.71 ! djm 82: static int
! 83: ssh_rsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
! 84: const char *typename, enum sshkey_serialize_rep opts)
! 85: {
! 86: int r;
! 87: const BIGNUM *rsa_n, *rsa_e;
! 88:
! 89: if (key->rsa == NULL)
! 90: return SSH_ERR_INVALID_ARGUMENT;
! 91: RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL);
! 92: if ((r = sshbuf_put_cstring(b, typename)) != 0 ||
! 93: (r = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
! 94: (r = sshbuf_put_bignum2(b, rsa_n)) != 0)
! 95: return r;
! 96:
! 97: return 0;
! 98: }
! 99:
1.55 markus 100: static const char *
101: rsa_hash_alg_ident(int hash_alg)
102: {
103: switch (hash_alg) {
104: case SSH_DIGEST_SHA1:
105: return "ssh-rsa";
106: case SSH_DIGEST_SHA256:
107: return "rsa-sha2-256";
108: case SSH_DIGEST_SHA512:
109: return "rsa-sha2-512";
110: }
111: return NULL;
112: }
113:
1.67 djm 114: /*
115: * Returns the hash algorithm ID for a given algorithm identifier as used
116: * inside the signature blob,
117: */
1.55 markus 118: static int
1.67 djm 119: rsa_hash_id_from_ident(const char *ident)
1.55 markus 120: {
1.67 djm 121: if (strcmp(ident, "ssh-rsa") == 0)
1.55 markus 122: return SSH_DIGEST_SHA1;
123: if (strcmp(ident, "rsa-sha2-256") == 0)
124: return SSH_DIGEST_SHA256;
125: if (strcmp(ident, "rsa-sha2-512") == 0)
126: return SSH_DIGEST_SHA512;
127: return -1;
128: }
129:
1.67 djm 130: /*
131: * Return the hash algorithm ID for the specified key name. This includes
132: * all the cases of rsa_hash_id_from_ident() but also the certificate key
133: * types.
134: */
135: static int
136: rsa_hash_id_from_keyname(const char *alg)
137: {
138: int r;
139:
140: if ((r = rsa_hash_id_from_ident(alg)) != -1)
141: return r;
142: if (strcmp(alg, "ssh-rsa-cert-v01@openssh.com") == 0)
143: return SSH_DIGEST_SHA1;
144: if (strcmp(alg, "rsa-sha2-256-cert-v01@openssh.com") == 0)
145: return SSH_DIGEST_SHA256;
146: if (strcmp(alg, "rsa-sha2-512-cert-v01@openssh.com") == 0)
147: return SSH_DIGEST_SHA512;
148: return -1;
149: }
150:
1.55 markus 151: static int
152: rsa_hash_alg_nid(int type)
153: {
154: switch (type) {
155: case SSH_DIGEST_SHA1:
156: return NID_sha1;
157: case SSH_DIGEST_SHA256:
158: return NID_sha256;
159: case SSH_DIGEST_SHA512:
160: return NID_sha512;
161: default:
162: return -1;
163: }
1.62 djm 164: }
165:
166: int
1.68 djm 167: ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)
1.62 djm 168: {
1.68 djm 169: const BIGNUM *rsa_p, *rsa_q, *rsa_d;
170: BIGNUM *aux = NULL, *d_consttime = NULL;
171: BIGNUM *rsa_dmq1 = NULL, *rsa_dmp1 = NULL, *rsa_iqmp = NULL;
1.62 djm 172: BN_CTX *ctx = NULL;
173: int r;
174:
175: if (key == NULL || key->rsa == NULL ||
176: sshkey_type_plain(key->type) != KEY_RSA)
177: return SSH_ERR_INVALID_ARGUMENT;
178:
1.68 djm 179: RSA_get0_key(key->rsa, NULL, NULL, &rsa_d);
180: RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
181:
1.62 djm 182: if ((ctx = BN_CTX_new()) == NULL)
183: return SSH_ERR_ALLOC_FAIL;
1.68 djm 184: if ((aux = BN_new()) == NULL ||
185: (rsa_dmq1 = BN_new()) == NULL ||
186: (rsa_dmp1 = BN_new()) == NULL)
187: return SSH_ERR_ALLOC_FAIL;
188: if ((d_consttime = BN_dup(rsa_d)) == NULL ||
189: (rsa_iqmp = BN_dup(iqmp)) == NULL) {
1.62 djm 190: r = SSH_ERR_ALLOC_FAIL;
191: goto out;
192: }
1.66 jsing 193: BN_set_flags(aux, BN_FLG_CONSTTIME);
1.68 djm 194: BN_set_flags(d_consttime, BN_FLG_CONSTTIME);
1.62 djm 195:
1.68 djm 196: if ((BN_sub(aux, rsa_q, BN_value_one()) == 0) ||
197: (BN_mod(rsa_dmq1, d_consttime, aux, ctx) == 0) ||
198: (BN_sub(aux, rsa_p, BN_value_one()) == 0) ||
199: (BN_mod(rsa_dmp1, d_consttime, aux, ctx) == 0)) {
200: r = SSH_ERR_LIBCRYPTO_ERROR;
201: goto out;
202: }
203: if (!RSA_set0_crt_params(key->rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) {
1.62 djm 204: r = SSH_ERR_LIBCRYPTO_ERROR;
205: goto out;
206: }
1.68 djm 207: rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; /* transferred */
208: /* success */
1.62 djm 209: r = 0;
210: out:
211: BN_clear_free(aux);
1.68 djm 212: BN_clear_free(d_consttime);
213: BN_clear_free(rsa_dmp1);
214: BN_clear_free(rsa_dmq1);
215: BN_clear_free(rsa_iqmp);
1.62 djm 216: BN_CTX_free(ctx);
217: return r;
1.55 markus 218: }
219:
1.1 markus 220: /* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
221: int
1.52 djm 222: ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
1.55 markus 223: const u_char *data, size_t datalen, const char *alg_ident)
1.1 markus 224: {
1.68 djm 225: const BIGNUM *rsa_n;
1.52 djm 226: u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
1.65 jsing 227: size_t slen = 0;
1.52 djm 228: u_int dlen, len;
1.55 markus 229: int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
1.52 djm 230: struct sshbuf *b = NULL;
231:
232: if (lenp != NULL)
233: *lenp = 0;
234: if (sigp != NULL)
235: *sigp = NULL;
236:
1.60 djm 237: if (alg_ident == NULL || strlen(alg_ident) == 0)
1.56 markus 238: hash_alg = SSH_DIGEST_SHA1;
239: else
1.67 djm 240: hash_alg = rsa_hash_id_from_keyname(alg_ident);
1.55 markus 241: if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
1.61 djm 242: sshkey_type_plain(key->type) != KEY_RSA)
1.52 djm 243: return SSH_ERR_INVALID_ARGUMENT;
1.68 djm 244: RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
245: if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
1.61 djm 246: return SSH_ERR_KEY_LENGTH;
1.52 djm 247: slen = RSA_size(key->rsa);
248: if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
249: return SSH_ERR_INVALID_ARGUMENT;
1.47 djm 250:
1.50 djm 251: /* hash the data */
1.55 markus 252: nid = rsa_hash_alg_nid(hash_alg);
1.52 djm 253: if ((dlen = ssh_digest_bytes(hash_alg)) == 0)
254: return SSH_ERR_INTERNAL_ERROR;
255: if ((ret = ssh_digest_memory(hash_alg, data, datalen,
256: digest, sizeof(digest))) != 0)
257: goto out;
258:
259: if ((sig = malloc(slen)) == NULL) {
260: ret = SSH_ERR_ALLOC_FAIL;
261: goto out;
1.50 djm 262: }
1.1 markus 263:
1.52 djm 264: if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) {
265: ret = SSH_ERR_LIBCRYPTO_ERROR;
266: goto out;
1.1 markus 267: }
268: if (len < slen) {
1.52 djm 269: size_t diff = slen - len;
1.1 markus 270: memmove(sig + diff, sig, len);
1.51 djm 271: explicit_bzero(sig, diff);
1.1 markus 272: } else if (len > slen) {
1.52 djm 273: ret = SSH_ERR_INTERNAL_ERROR;
274: goto out;
1.1 markus 275: }
276: /* encode signature */
1.52 djm 277: if ((b = sshbuf_new()) == NULL) {
278: ret = SSH_ERR_ALLOC_FAIL;
279: goto out;
280: }
1.55 markus 281: if ((ret = sshbuf_put_cstring(b, rsa_hash_alg_ident(hash_alg))) != 0 ||
1.52 djm 282: (ret = sshbuf_put_string(b, sig, slen)) != 0)
283: goto out;
284: len = sshbuf_len(b);
285: if (sigp != NULL) {
286: if ((*sigp = malloc(len)) == NULL) {
287: ret = SSH_ERR_ALLOC_FAIL;
288: goto out;
289: }
290: memcpy(*sigp, sshbuf_ptr(b), len);
291: }
1.23 markus 292: if (lenp != NULL)
293: *lenp = len;
1.52 djm 294: ret = 0;
295: out:
296: explicit_bzero(digest, sizeof(digest));
1.65 jsing 297: freezero(sig, slen);
1.58 mmcc 298: sshbuf_free(b);
1.53 djm 299: return ret;
1.1 markus 300: }
301:
302: int
1.52 djm 303: ssh_rsa_verify(const struct sshkey *key,
1.63 djm 304: const u_char *sig, size_t siglen, const u_char *data, size_t datalen,
305: const char *alg)
1.1 markus 306: {
1.68 djm 307: const BIGNUM *rsa_n;
1.63 djm 308: char *sigtype = NULL;
1.67 djm 309: int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
1.65 jsing 310: size_t len = 0, diff, modlen, dlen;
1.52 djm 311: struct sshbuf *b = NULL;
312: u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
313:
314: if (key == NULL || key->rsa == NULL ||
315: sshkey_type_plain(key->type) != KEY_RSA ||
1.59 djm 316: sig == NULL || siglen == 0)
1.52 djm 317: return SSH_ERR_INVALID_ARGUMENT;
1.68 djm 318: RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
319: if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
1.61 djm 320: return SSH_ERR_KEY_LENGTH;
1.52 djm 321:
1.55 markus 322: if ((b = sshbuf_from(sig, siglen)) == NULL)
1.52 djm 323: return SSH_ERR_ALLOC_FAIL;
1.63 djm 324: if (sshbuf_get_cstring(b, &sigtype, NULL) != 0) {
1.52 djm 325: ret = SSH_ERR_INVALID_FORMAT;
326: goto out;
327: }
1.67 djm 328: if ((hash_alg = rsa_hash_id_from_ident(sigtype)) == -1) {
329: ret = SSH_ERR_KEY_TYPE_MISMATCH;
1.63 djm 330: goto out;
331: }
1.67 djm 332: /*
333: * Allow ssh-rsa-cert-v01 certs to generate SHA2 signatures for
334: * legacy reasons, but otherwise the signature type should match.
335: */
336: if (alg != NULL && strcmp(alg, "ssh-rsa-cert-v01@openssh.com") != 0) {
337: if ((want_alg = rsa_hash_id_from_keyname(alg)) == -1) {
338: ret = SSH_ERR_INVALID_ARGUMENT;
339: goto out;
340: }
341: if (hash_alg != want_alg) {
342: ret = SSH_ERR_SIGNATURE_INVALID;
343: goto out;
344: }
1.1 markus 345: }
1.52 djm 346: if (sshbuf_get_string(b, &sigblob, &len) != 0) {
347: ret = SSH_ERR_INVALID_FORMAT;
348: goto out;
349: }
350: if (sshbuf_len(b) != 0) {
351: ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
352: goto out;
1.19 markus 353: }
354: /* RSA_verify expects a signature of RSA_size */
355: modlen = RSA_size(key->rsa);
356: if (len > modlen) {
1.52 djm 357: ret = SSH_ERR_KEY_BITS_MISMATCH;
358: goto out;
1.19 markus 359: } else if (len < modlen) {
1.52 djm 360: diff = modlen - len;
361: osigblob = sigblob;
362: if ((sigblob = realloc(sigblob, modlen)) == NULL) {
363: sigblob = osigblob; /* put it back for clear/free */
364: ret = SSH_ERR_ALLOC_FAIL;
365: goto out;
366: }
1.19 markus 367: memmove(sigblob + diff, sigblob, len);
1.51 djm 368: explicit_bzero(sigblob, diff);
1.19 markus 369: len = modlen;
1.1 markus 370: }
1.50 djm 371: if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
1.52 djm 372: ret = SSH_ERR_INTERNAL_ERROR;
373: goto out;
1.7 markus 374: }
1.52 djm 375: if ((ret = ssh_digest_memory(hash_alg, data, datalen,
376: digest, sizeof(digest))) != 0)
377: goto out;
1.1 markus 378:
1.50 djm 379: ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
380: key->rsa);
1.52 djm 381: out:
1.65 jsing 382: freezero(sigblob, len);
1.63 djm 383: free(sigtype);
1.58 mmcc 384: sshbuf_free(b);
1.51 djm 385: explicit_bzero(digest, sizeof(digest));
1.25 markus 386: return ret;
387: }
388:
389: /*
390: * See:
391: * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
392: * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
393: */
1.55 markus 394:
1.25 markus 395: /*
396: * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
397: * oiw(14) secsig(3) algorithms(2) 26 }
398: */
399: static const u_char id_sha1[] = {
400: 0x30, 0x21, /* type Sequence, length 0x21 (33) */
401: 0x30, 0x09, /* type Sequence, length 0x09 */
402: 0x06, 0x05, /* type OID, length 0x05 */
403: 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
404: 0x05, 0x00, /* NULL */
405: 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
406: };
407:
1.55 markus 408: /*
409: * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
410: * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
411: * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
412: * id-sha256(1) }
413: */
414: static const u_char id_sha256[] = {
415: 0x30, 0x31, /* type Sequence, length 0x31 (49) */
416: 0x30, 0x0d, /* type Sequence, length 0x0d (13) */
417: 0x06, 0x09, /* type OID, length 0x09 */
418: 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */
419: 0x05, 0x00, /* NULL */
420: 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */
421: };
422:
423: /*
424: * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
425: * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
426: * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
427: * id-sha256(3) }
428: */
429: static const u_char id_sha512[] = {
430: 0x30, 0x51, /* type Sequence, length 0x51 (81) */
431: 0x30, 0x0d, /* type Sequence, length 0x0d (13) */
432: 0x06, 0x09, /* type OID, length 0x09 */
433: 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */
434: 0x05, 0x00, /* NULL */
435: 0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */
436: };
437:
438: static int
439: rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp)
440: {
441: switch (hash_alg) {
442: case SSH_DIGEST_SHA1:
443: *oidp = id_sha1;
444: *oidlenp = sizeof(id_sha1);
445: break;
446: case SSH_DIGEST_SHA256:
447: *oidp = id_sha256;
448: *oidlenp = sizeof(id_sha256);
449: break;
450: case SSH_DIGEST_SHA512:
451: *oidp = id_sha512;
452: *oidlenp = sizeof(id_sha512);
453: break;
454: default:
455: return SSH_ERR_INVALID_ARGUMENT;
456: }
457: return 0;
458: }
459:
1.25 markus 460: static int
1.52 djm 461: openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen,
462: u_char *sigbuf, size_t siglen, RSA *rsa)
1.25 markus 463: {
1.54 djm 464: size_t rsasize = 0, oidlen = 0, hlen = 0;
465: int ret, len, oidmatch, hashmatch;
1.25 markus 466: const u_char *oid = NULL;
467: u_char *decrypted = NULL;
468:
1.55 markus 469: if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0)
470: return ret;
1.52 djm 471: ret = SSH_ERR_INTERNAL_ERROR;
1.55 markus 472: hlen = ssh_digest_bytes(hash_alg);
1.25 markus 473: if (hashlen != hlen) {
1.52 djm 474: ret = SSH_ERR_INVALID_ARGUMENT;
1.25 markus 475: goto done;
476: }
477: rsasize = RSA_size(rsa);
1.52 djm 478: if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM ||
479: siglen == 0 || siglen > rsasize) {
480: ret = SSH_ERR_INVALID_ARGUMENT;
481: goto done;
482: }
483: if ((decrypted = malloc(rsasize)) == NULL) {
484: ret = SSH_ERR_ALLOC_FAIL;
1.25 markus 485: goto done;
486: }
487: if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
488: RSA_PKCS1_PADDING)) < 0) {
1.52 djm 489: ret = SSH_ERR_LIBCRYPTO_ERROR;
1.25 markus 490: goto done;
491: }
1.52 djm 492: if (len < 0 || (size_t)len != hlen + oidlen) {
493: ret = SSH_ERR_INVALID_FORMAT;
1.25 markus 494: goto done;
495: }
1.44 djm 496: oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0;
497: hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0;
1.52 djm 498: if (!oidmatch || !hashmatch) {
499: ret = SSH_ERR_SIGNATURE_INVALID;
1.25 markus 500: goto done;
501: }
1.52 djm 502: ret = 0;
503: done:
1.65 jsing 504: freezero(decrypted, rsasize);
1.1 markus 505: return ret;
506: }
1.69 djm 507:
508: static const struct sshkey_impl_funcs sshkey_rsa_funcs = {
509: /* .size = */ ssh_rsa_size,
510: /* .alloc = */ ssh_rsa_alloc,
511: /* .cleanup = */ ssh_rsa_cleanup,
1.70 djm 512: /* .equal = */ ssh_rsa_equal,
1.71 ! djm 513: /* .ssh_serialize_public = */ ssh_rsa_serialize_public,
1.69 djm 514: };
515:
516: const struct sshkey_impl sshkey_rsa_impl = {
517: /* .name = */ "ssh-rsa",
518: /* .shortname = */ "RSA",
519: /* .sigalg = */ NULL,
520: /* .type = */ KEY_RSA,
521: /* .nid = */ 0,
522: /* .cert = */ 0,
523: /* .sigonly = */ 0,
524: /* .keybits = */ 0,
525: /* .funcs = */ &sshkey_rsa_funcs,
526: };
527:
528: const struct sshkey_impl sshkey_rsa_cert_impl = {
529: /* .name = */ "ssh-rsa-cert-v01@openssh.com",
530: /* .shortname = */ "RSA-CERT",
531: /* .sigalg = */ NULL,
532: /* .type = */ KEY_RSA_CERT,
533: /* .nid = */ 0,
534: /* .cert = */ 1,
535: /* .sigonly = */ 0,
536: /* .keybits = */ 0,
537: /* .funcs = */ &sshkey_rsa_funcs,
538: };
539:
540: /* SHA2 signature algorithms */
541:
542: const struct sshkey_impl sshkey_rsa_sha256_impl = {
543: /* .name = */ "rsa-sha2-256",
544: /* .shortname = */ "RSA",
545: /* .sigalg = */ NULL,
546: /* .type = */ KEY_RSA,
547: /* .nid = */ 0,
548: /* .cert = */ 0,
549: /* .sigonly = */ 1,
550: /* .keybits = */ 0,
551: /* .funcs = */ &sshkey_rsa_funcs,
552: };
553:
554: const struct sshkey_impl sshkey_rsa_sha512_impl = {
555: /* .name = */ "rsa-sha2-512",
556: /* .shortname = */ "RSA",
557: /* .sigalg = */ NULL,
558: /* .type = */ KEY_RSA,
559: /* .nid = */ 0,
560: /* .cert = */ 0,
561: /* .sigonly = */ 1,
562: /* .keybits = */ 0,
563: /* .funcs = */ &sshkey_rsa_funcs,
564: };
565:
566: const struct sshkey_impl sshkey_rsa_sha256_cert_impl = {
567: /* .name = */ "rsa-sha2-256-cert-v01@openssh.com",
568: /* .shortname = */ "RSA-CERT",
569: /* .sigalg = */ "rsa-sha2-256",
570: /* .type = */ KEY_RSA_CERT,
571: /* .nid = */ 0,
572: /* .cert = */ 1,
573: /* .sigonly = */ 1,
574: /* .keybits = */ 0,
575: /* .funcs = */ &sshkey_rsa_funcs,
576: };
577:
578: const struct sshkey_impl sshkey_rsa_sha512_cert_impl = {
579: /* .name = */ "rsa-sha2-512-cert-v01@openssh.com",
580: /* .shortname = */ "RSA-CERT",
581: /* .sigalg = */ "rsa-sha2-512",
582: /* .type = */ KEY_RSA_CERT,
583: /* .nid = */ 0,
584: /* .cert = */ 1,
585: /* .sigonly = */ 1,
586: /* .keybits = */ 0,
587: /* .funcs = */ &sshkey_rsa_funcs,
588: };