1 /* $OpenBSD: ssh-rsa.c,v 1.80 2024/08/15 00:51:51 djm Exp $ */ 2 /* 3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> 4 * 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. 8 * 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. 16 */ 17 18 #include "includes.h" 19 20 #ifdef WITH_OPENSSL 21 22 #include <sys/types.h> 23 24 #include <openssl/evp.h> 25 #include <openssl/err.h> 26 27 #include <stdarg.h> 28 #include <string.h> 29 30 #include "sshbuf.h" 31 #include "ssherr.h" 32 #define SSHKEY_INTERNAL 33 #include "sshkey.h" 34 #include "digest.h" 35 #include "log.h" 36 37 #include "openbsd-compat/openssl-compat.h" 38 39 static u_int 40 ssh_rsa_size(const struct sshkey *k) 41 { 42 if (k->pkey == NULL) 43 return 0; 44 return EVP_PKEY_bits(k->pkey); 45 } 46 47 static int 48 ssh_rsa_alloc(struct sshkey *k) 49 { 50 if ((k->pkey = EVP_PKEY_new()) == NULL) 51 return SSH_ERR_ALLOC_FAIL; 52 return 0; 53 } 54 55 static void 56 ssh_rsa_cleanup(struct sshkey *k) 57 { 58 EVP_PKEY_free(k->pkey); 59 k->pkey = NULL; 60 } 61 62 static int 63 ssh_rsa_equal(const struct sshkey *a, const struct sshkey *b) 64 { 65 if (a->pkey == NULL || b->pkey == NULL) 66 return 0; 67 return EVP_PKEY_cmp(a->pkey, b->pkey) == 1; 68 } 69 70 static int 71 ssh_rsa_serialize_public(const struct sshkey *key, struct sshbuf *b, 72 enum sshkey_serialize_rep opts) 73 { 74 int r; 75 const BIGNUM *rsa_n, *rsa_e; 76 const RSA *rsa; 77 78 if (key->pkey == NULL) 79 return SSH_ERR_INVALID_ARGUMENT; 80 if ((rsa = EVP_PKEY_get0_RSA(key->pkey)) == NULL) 81 return SSH_ERR_LIBCRYPTO_ERROR; 82 83 RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); 84 if ((r = sshbuf_put_bignum2(b, rsa_e)) != 0 || 85 (r = sshbuf_put_bignum2(b, rsa_n)) != 0) 86 return r; 87 88 return 0; 89 } 90 91 static int 92 ssh_rsa_serialize_private(const struct sshkey *key, struct sshbuf *b, 93 enum sshkey_serialize_rep opts) 94 { 95 int r; 96 const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q; 97 const RSA *rsa; 98 99 if ((rsa = EVP_PKEY_get0_RSA(key->pkey)) == NULL) 100 return SSH_ERR_LIBCRYPTO_ERROR; 101 RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); 102 RSA_get0_factors(rsa, &rsa_p, &rsa_q); 103 RSA_get0_crt_params(rsa, NULL, NULL, &rsa_iqmp); 104 105 if (!sshkey_is_cert(key)) { 106 /* Note: can't reuse ssh_rsa_serialize_public: e, n vs. n, e */ 107 if ((r = sshbuf_put_bignum2(b, rsa_n)) != 0 || 108 (r = sshbuf_put_bignum2(b, rsa_e)) != 0) 109 return r; 110 } 111 if ((r = sshbuf_put_bignum2(b, rsa_d)) != 0 || 112 (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 || 113 (r = sshbuf_put_bignum2(b, rsa_p)) != 0 || 114 (r = sshbuf_put_bignum2(b, rsa_q)) != 0) 115 return r; 116 117 return 0; 118 } 119 120 static int 121 ssh_rsa_generate(struct sshkey *k, int bits) 122 { 123 EVP_PKEY_CTX *ctx = NULL; 124 EVP_PKEY *res = NULL; 125 126 int ret = SSH_ERR_INTERNAL_ERROR; 127 128 if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE || 129 bits > SSHBUF_MAX_BIGNUM * 8) 130 return SSH_ERR_KEY_LENGTH; 131 132 if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) { 133 ret = SSH_ERR_ALLOC_FAIL; 134 goto out; 135 } 136 if (EVP_PKEY_keygen_init(ctx) <= 0) { 137 ret = SSH_ERR_LIBCRYPTO_ERROR; 138 goto out; 139 } 140 if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) { 141 ret = SSH_ERR_KEY_LENGTH; 142 goto out; 143 } 144 if (EVP_PKEY_keygen(ctx, &res) <= 0 || res == NULL) { 145 ret = SSH_ERR_LIBCRYPTO_ERROR; 146 goto out; 147 } 148 /* success */ 149 k->pkey = res; 150 ret = 0; 151 out: 152 EVP_PKEY_CTX_free(ctx); 153 return ret; 154 } 155 156 static int 157 ssh_rsa_copy_public(const struct sshkey *from, struct sshkey *to) 158 { 159 const BIGNUM *rsa_n, *rsa_e; 160 BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL; 161 int r = SSH_ERR_INTERNAL_ERROR; 162 const RSA *rsa_from; 163 RSA *rsa_to = NULL; 164 165 if ((rsa_from = EVP_PKEY_get0_RSA(from->pkey)) == NULL || 166 (rsa_to = RSA_new()) == NULL) 167 return SSH_ERR_LIBCRYPTO_ERROR; 168 169 RSA_get0_key(rsa_from, &rsa_n, &rsa_e, NULL); 170 if ((rsa_n_dup = BN_dup(rsa_n)) == NULL || 171 (rsa_e_dup = BN_dup(rsa_e)) == NULL) { 172 r = SSH_ERR_ALLOC_FAIL; 173 goto out; 174 } 175 if (!RSA_set0_key(rsa_to, rsa_n_dup, rsa_e_dup, NULL)) { 176 r = SSH_ERR_LIBCRYPTO_ERROR; 177 goto out; 178 } 179 rsa_n_dup = rsa_e_dup = NULL; /* transferred */ 180 181 if (EVP_PKEY_set1_RSA(to->pkey, rsa_to) != 1) { 182 r = SSH_ERR_LIBCRYPTO_ERROR; 183 goto out; 184 } 185 /* success */ 186 r = 0; 187 out: 188 RSA_free(rsa_to); 189 BN_clear_free(rsa_n_dup); 190 BN_clear_free(rsa_e_dup); 191 return r; 192 } 193 194 static int 195 ssh_rsa_deserialize_public(const char *ktype, struct sshbuf *b, 196 struct sshkey *key) 197 { 198 int ret = SSH_ERR_INTERNAL_ERROR; 199 BIGNUM *rsa_n = NULL, *rsa_e = NULL; 200 RSA *rsa = NULL; 201 202 if ((rsa = RSA_new()) == NULL) 203 return SSH_ERR_LIBCRYPTO_ERROR; 204 205 if (sshbuf_get_bignum2(b, &rsa_e) != 0 || 206 sshbuf_get_bignum2(b, &rsa_n) != 0) { 207 ret = SSH_ERR_INVALID_FORMAT; 208 goto out; 209 } 210 if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL)) { 211 ret = SSH_ERR_LIBCRYPTO_ERROR; 212 goto out; 213 } 214 rsa_n = rsa_e = NULL; /* transferred */ 215 if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) { 216 ret = SSH_ERR_LIBCRYPTO_ERROR; 217 goto out; 218 } 219 if ((ret = sshkey_check_rsa_length(key, 0)) != 0) 220 goto out; 221 #ifdef DEBUG_PK 222 RSA_print_fp(stderr, rsa, 8); 223 #endif 224 /* success */ 225 ret = 0; 226 out: 227 RSA_free(rsa); 228 BN_clear_free(rsa_n); 229 BN_clear_free(rsa_e); 230 return ret; 231 } 232 233 static int 234 ssh_rsa_deserialize_private(const char *ktype, struct sshbuf *b, 235 struct sshkey *key) 236 { 237 int r; 238 BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; 239 BIGNUM *rsa_iqmp = NULL, *rsa_p = NULL, *rsa_q = NULL; 240 BIGNUM *rsa_dmp1 = NULL, *rsa_dmq1 = NULL; 241 RSA *rsa = NULL; 242 243 if (sshkey_is_cert(key)) { 244 /* sshkey_private_deserialize already has pubkey from cert */ 245 if ((rsa = EVP_PKEY_get1_RSA(key->pkey)) == NULL) { 246 r = SSH_ERR_LIBCRYPTO_ERROR; 247 goto out; 248 } 249 } else { 250 if ((rsa = RSA_new()) == NULL) { 251 r = SSH_ERR_LIBCRYPTO_ERROR; 252 goto out; 253 } 254 /* Note: can't reuse ssh_rsa_deserialize_public: e,n vs. n,e */ 255 if ((r = sshbuf_get_bignum2(b, &rsa_n)) != 0 || 256 (r = sshbuf_get_bignum2(b, &rsa_e)) != 0) 257 goto out; 258 if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL)) { 259 r = SSH_ERR_LIBCRYPTO_ERROR; 260 goto out; 261 } 262 rsa_n = rsa_e = NULL; /* transferred */ 263 } 264 if ((r = sshbuf_get_bignum2(b, &rsa_d)) != 0 || 265 (r = sshbuf_get_bignum2(b, &rsa_iqmp)) != 0 || 266 (r = sshbuf_get_bignum2(b, &rsa_p)) != 0 || 267 (r = sshbuf_get_bignum2(b, &rsa_q)) != 0) 268 goto out; 269 if ((r = ssh_rsa_complete_crt_parameters(rsa_d, rsa_p, rsa_q, 270 rsa_iqmp, &rsa_dmp1, &rsa_dmq1)) != 0) 271 goto out; 272 if (!RSA_set0_key(rsa, NULL, NULL, rsa_d)) { 273 r = SSH_ERR_LIBCRYPTO_ERROR; 274 goto out; 275 } 276 rsa_d = NULL; /* transferred */ 277 if (!RSA_set0_factors(rsa, rsa_p, rsa_q)) { 278 r = SSH_ERR_LIBCRYPTO_ERROR; 279 goto out; 280 } 281 rsa_p = rsa_q = NULL; /* transferred */ 282 if (!RSA_set0_crt_params(rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) { 283 r = SSH_ERR_LIBCRYPTO_ERROR; 284 goto out; 285 } 286 rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; 287 if (RSA_blinding_on(rsa, NULL) != 1) { 288 r = SSH_ERR_LIBCRYPTO_ERROR; 289 goto out; 290 } 291 if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) { 292 r = SSH_ERR_LIBCRYPTO_ERROR; 293 goto out; 294 } 295 if ((r = sshkey_check_rsa_length(key, 0)) != 0) 296 goto out; 297 /* success */ 298 r = 0; 299 out: 300 RSA_free(rsa); 301 BN_clear_free(rsa_n); 302 BN_clear_free(rsa_e); 303 BN_clear_free(rsa_d); 304 BN_clear_free(rsa_p); 305 BN_clear_free(rsa_q); 306 BN_clear_free(rsa_iqmp); 307 BN_clear_free(rsa_dmp1); 308 BN_clear_free(rsa_dmq1); 309 return r; 310 } 311 312 static const char * 313 rsa_hash_alg_ident(int hash_alg) 314 { 315 switch (hash_alg) { 316 case SSH_DIGEST_SHA1: 317 return "ssh-rsa"; 318 case SSH_DIGEST_SHA256: 319 return "rsa-sha2-256"; 320 case SSH_DIGEST_SHA512: 321 return "rsa-sha2-512"; 322 } 323 return NULL; 324 } 325 326 /* 327 * Returns the hash algorithm ID for a given algorithm identifier as used 328 * inside the signature blob, 329 */ 330 static int 331 rsa_hash_id_from_ident(const char *ident) 332 { 333 if (strcmp(ident, "ssh-rsa") == 0) 334 return SSH_DIGEST_SHA1; 335 if (strcmp(ident, "rsa-sha2-256") == 0) 336 return SSH_DIGEST_SHA256; 337 if (strcmp(ident, "rsa-sha2-512") == 0) 338 return SSH_DIGEST_SHA512; 339 return -1; 340 } 341 342 /* 343 * Return the hash algorithm ID for the specified key name. This includes 344 * all the cases of rsa_hash_id_from_ident() but also the certificate key 345 * types. 346 */ 347 static int 348 rsa_hash_id_from_keyname(const char *alg) 349 { 350 int r; 351 352 if ((r = rsa_hash_id_from_ident(alg)) != -1) 353 return r; 354 if (strcmp(alg, "ssh-rsa-cert-v01@openssh.com") == 0) 355 return SSH_DIGEST_SHA1; 356 if (strcmp(alg, "rsa-sha2-256-cert-v01@openssh.com") == 0) 357 return SSH_DIGEST_SHA256; 358 if (strcmp(alg, "rsa-sha2-512-cert-v01@openssh.com") == 0) 359 return SSH_DIGEST_SHA512; 360 return -1; 361 } 362 363 int 364 ssh_rsa_complete_crt_parameters(const BIGNUM *rsa_d, const BIGNUM *rsa_p, 365 const BIGNUM *rsa_q, const BIGNUM *rsa_iqmp, BIGNUM **rsa_dmp1, 366 BIGNUM **rsa_dmq1) 367 { 368 BIGNUM *aux = NULL, *d_consttime = NULL; 369 BN_CTX *ctx = NULL; 370 int r; 371 372 *rsa_dmq1 = *rsa_dmp1 = NULL; 373 if ((ctx = BN_CTX_new()) == NULL) 374 return SSH_ERR_ALLOC_FAIL; 375 if ((aux = BN_new()) == NULL || 376 (*rsa_dmq1 = BN_new()) == NULL || 377 (*rsa_dmp1 = BN_new()) == NULL) 378 return SSH_ERR_ALLOC_FAIL; 379 if ((d_consttime = BN_dup(rsa_d)) == NULL) { 380 r = SSH_ERR_ALLOC_FAIL; 381 goto out; 382 } 383 BN_set_flags(aux, BN_FLG_CONSTTIME); 384 BN_set_flags(d_consttime, BN_FLG_CONSTTIME); 385 386 if ((BN_sub(aux, rsa_q, BN_value_one()) == 0) || 387 (BN_mod(*rsa_dmq1, d_consttime, aux, ctx) == 0) || 388 (BN_sub(aux, rsa_p, BN_value_one()) == 0) || 389 (BN_mod(*rsa_dmp1, d_consttime, aux, ctx) == 0)) { 390 r = SSH_ERR_LIBCRYPTO_ERROR; 391 goto out; 392 } 393 /* success */ 394 r = 0; 395 out: 396 BN_clear_free(aux); 397 BN_clear_free(d_consttime); 398 BN_CTX_free(ctx); 399 return r; 400 } 401 402 /* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */ 403 static int 404 ssh_rsa_sign(struct sshkey *key, 405 u_char **sigp, size_t *lenp, 406 const u_char *data, size_t datalen, 407 const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) 408 { 409 u_char *sig = NULL; 410 size_t diff, len = 0; 411 int slen = 0; 412 int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; 413 struct sshbuf *b = NULL; 414 415 if (lenp != NULL) 416 *lenp = 0; 417 if (sigp != NULL) 418 *sigp = NULL; 419 420 if (alg == NULL || strlen(alg) == 0) 421 hash_alg = SSH_DIGEST_SHA1; 422 else 423 hash_alg = rsa_hash_id_from_keyname(alg); 424 425 if (key == NULL || key->pkey == NULL || hash_alg == -1 || 426 sshkey_type_plain(key->type) != KEY_RSA) 427 return SSH_ERR_INVALID_ARGUMENT; 428 slen = EVP_PKEY_size(key->pkey); 429 if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) 430 return SSH_ERR_INVALID_ARGUMENT; 431 if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE) 432 return SSH_ERR_KEY_LENGTH; 433 434 if ((ret = sshkey_pkey_digest_sign(key->pkey, hash_alg, &sig, &len, 435 data, datalen)) < 0) 436 goto out; 437 if (len < (size_t)slen) { 438 diff = slen - len; 439 memmove(sig + diff, sig, len); 440 explicit_bzero(sig, diff); 441 } else if (len > (size_t)slen) { 442 ret = SSH_ERR_INTERNAL_ERROR; 443 goto out; 444 } 445 446 /* encode signature */ 447 if ((b = sshbuf_new()) == NULL) { 448 ret = SSH_ERR_ALLOC_FAIL; 449 goto out; 450 } 451 if ((ret = sshbuf_put_cstring(b, rsa_hash_alg_ident(hash_alg))) != 0 || 452 (ret = sshbuf_put_string(b, sig, slen)) != 0) 453 goto out; 454 len = sshbuf_len(b); 455 if (sigp != NULL) { 456 if ((*sigp = malloc(len)) == NULL) { 457 ret = SSH_ERR_ALLOC_FAIL; 458 goto out; 459 } 460 memcpy(*sigp, sshbuf_ptr(b), len); 461 } 462 if (lenp != NULL) 463 *lenp = len; 464 ret = 0; 465 out: 466 freezero(sig, slen); 467 sshbuf_free(b); 468 return ret; 469 } 470 471 static int 472 ssh_rsa_verify(const struct sshkey *key, 473 const u_char *sig, size_t siglen, 474 const u_char *data, size_t dlen, const char *alg, u_int compat, 475 struct sshkey_sig_details **detailsp) 476 { 477 char *sigtype = NULL; 478 int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR; 479 size_t len = 0, diff, modlen, rsasize; 480 struct sshbuf *b = NULL; 481 u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; 482 483 if (key == NULL || key->pkey == NULL || 484 sshkey_type_plain(key->type) != KEY_RSA || 485 sig == NULL || siglen == 0) 486 return SSH_ERR_INVALID_ARGUMENT; 487 if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE) 488 return SSH_ERR_KEY_LENGTH; 489 490 if ((b = sshbuf_from(sig, siglen)) == NULL) 491 return SSH_ERR_ALLOC_FAIL; 492 if (sshbuf_get_cstring(b, &sigtype, NULL) != 0) { 493 ret = SSH_ERR_INVALID_FORMAT; 494 goto out; 495 } 496 if ((hash_alg = rsa_hash_id_from_ident(sigtype)) == -1) { 497 ret = SSH_ERR_KEY_TYPE_MISMATCH; 498 goto out; 499 } 500 /* 501 * Allow ssh-rsa-cert-v01 certs to generate SHA2 signatures for 502 * legacy reasons, but otherwise the signature type should match. 503 */ 504 if (alg != NULL && strcmp(alg, "ssh-rsa-cert-v01@openssh.com") != 0) { 505 if ((want_alg = rsa_hash_id_from_keyname(alg)) == -1) { 506 ret = SSH_ERR_INVALID_ARGUMENT; 507 goto out; 508 } 509 if (hash_alg != want_alg) { 510 ret = SSH_ERR_SIGNATURE_INVALID; 511 goto out; 512 } 513 } 514 if (sshbuf_get_string(b, &sigblob, &len) != 0) { 515 ret = SSH_ERR_INVALID_FORMAT; 516 goto out; 517 } 518 if (sshbuf_len(b) != 0) { 519 ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; 520 goto out; 521 } 522 /* RSA_verify expects a signature of RSA_size */ 523 modlen = EVP_PKEY_size(key->pkey); 524 if (len > modlen) { 525 ret = SSH_ERR_KEY_BITS_MISMATCH; 526 goto out; 527 } else if (len < modlen) { 528 diff = modlen - len; 529 osigblob = sigblob; 530 if ((sigblob = realloc(sigblob, modlen)) == NULL) { 531 sigblob = osigblob; /* put it back for clear/free */ 532 ret = SSH_ERR_ALLOC_FAIL; 533 goto out; 534 } 535 memmove(sigblob + diff, sigblob, len); 536 explicit_bzero(sigblob, diff); 537 len = modlen; 538 } 539 540 rsasize = EVP_PKEY_size(key->pkey); 541 if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || 542 len == 0 || len > rsasize) { 543 ret = SSH_ERR_INVALID_ARGUMENT; 544 goto out; 545 } 546 ret = sshkey_pkey_digest_verify(key->pkey, hash_alg, data, dlen, 547 sigblob, len); 548 549 out: 550 freezero(sigblob, len); 551 free(sigtype); 552 sshbuf_free(b); 553 explicit_bzero(digest, sizeof(digest)); 554 return ret; 555 } 556 557 static const struct sshkey_impl_funcs sshkey_rsa_funcs = { 558 /* .size = */ ssh_rsa_size, 559 /* .alloc = */ ssh_rsa_alloc, 560 /* .cleanup = */ ssh_rsa_cleanup, 561 /* .equal = */ ssh_rsa_equal, 562 /* .ssh_serialize_public = */ ssh_rsa_serialize_public, 563 /* .ssh_deserialize_public = */ ssh_rsa_deserialize_public, 564 /* .ssh_serialize_private = */ ssh_rsa_serialize_private, 565 /* .ssh_deserialize_private = */ ssh_rsa_deserialize_private, 566 /* .generate = */ ssh_rsa_generate, 567 /* .copy_public = */ ssh_rsa_copy_public, 568 /* .sign = */ ssh_rsa_sign, 569 /* .verify = */ ssh_rsa_verify, 570 }; 571 572 const struct sshkey_impl sshkey_rsa_impl = { 573 /* .name = */ "ssh-rsa", 574 /* .shortname = */ "RSA", 575 /* .sigalg = */ NULL, 576 /* .type = */ KEY_RSA, 577 /* .nid = */ 0, 578 /* .cert = */ 0, 579 /* .sigonly = */ 0, 580 /* .keybits = */ 0, 581 /* .funcs = */ &sshkey_rsa_funcs, 582 }; 583 584 const struct sshkey_impl sshkey_rsa_cert_impl = { 585 /* .name = */ "ssh-rsa-cert-v01@openssh.com", 586 /* .shortname = */ "RSA-CERT", 587 /* .sigalg = */ NULL, 588 /* .type = */ KEY_RSA_CERT, 589 /* .nid = */ 0, 590 /* .cert = */ 1, 591 /* .sigonly = */ 0, 592 /* .keybits = */ 0, 593 /* .funcs = */ &sshkey_rsa_funcs, 594 }; 595 596 /* SHA2 signature algorithms */ 597 598 const struct sshkey_impl sshkey_rsa_sha256_impl = { 599 /* .name = */ "rsa-sha2-256", 600 /* .shortname = */ "RSA", 601 /* .sigalg = */ NULL, 602 /* .type = */ KEY_RSA, 603 /* .nid = */ 0, 604 /* .cert = */ 0, 605 /* .sigonly = */ 1, 606 /* .keybits = */ 0, 607 /* .funcs = */ &sshkey_rsa_funcs, 608 }; 609 610 const struct sshkey_impl sshkey_rsa_sha512_impl = { 611 /* .name = */ "rsa-sha2-512", 612 /* .shortname = */ "RSA", 613 /* .sigalg = */ NULL, 614 /* .type = */ KEY_RSA, 615 /* .nid = */ 0, 616 /* .cert = */ 0, 617 /* .sigonly = */ 1, 618 /* .keybits = */ 0, 619 /* .funcs = */ &sshkey_rsa_funcs, 620 }; 621 622 const struct sshkey_impl sshkey_rsa_sha256_cert_impl = { 623 /* .name = */ "rsa-sha2-256-cert-v01@openssh.com", 624 /* .shortname = */ "RSA-CERT", 625 /* .sigalg = */ "rsa-sha2-256", 626 /* .type = */ KEY_RSA_CERT, 627 /* .nid = */ 0, 628 /* .cert = */ 1, 629 /* .sigonly = */ 1, 630 /* .keybits = */ 0, 631 /* .funcs = */ &sshkey_rsa_funcs, 632 }; 633 634 const struct sshkey_impl sshkey_rsa_sha512_cert_impl = { 635 /* .name = */ "rsa-sha2-512-cert-v01@openssh.com", 636 /* .shortname = */ "RSA-CERT", 637 /* .sigalg = */ "rsa-sha2-512", 638 /* .type = */ KEY_RSA_CERT, 639 /* .nid = */ 0, 640 /* .cert = */ 1, 641 /* .sigonly = */ 1, 642 /* .keybits = */ 0, 643 /* .funcs = */ &sshkey_rsa_funcs, 644 }; 645 #endif /* WITH_OPENSSL */ 646