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