1323124Sdes/* $OpenBSD: key.c,v 1.130 2016/05/02 09:36:42 djm Exp $ */ 258582Skris/* 3295367Sdes * placed in the public domain 458582Skris */ 5162856Sdes 676262Sgreen#include "includes.h" 758582Skris 8162856Sdes#include <sys/types.h> 9295367Sdes#include <errno.h> 10162856Sdes#include <stdarg.h> 11162856Sdes#include <stdio.h> 12295367Sdes#include <limits.h> 13162856Sdes 14295367Sdes#define SSH_KEY_NO_DEFINE 1558582Skris#include "key.h" 16295367Sdes 17295367Sdes#include "compat.h" 18295367Sdes#include "sshkey.h" 19295367Sdes#include "ssherr.h" 2076262Sgreen#include "log.h" 21295367Sdes#include "authfile.h" 2258582Skris 23204917Sdesvoid 24204917Sdeskey_add_private(Key *k) 2576262Sgreen{ 26295367Sdes int r; 27295367Sdes 28295367Sdes if ((r = sshkey_add_private(k)) != 0) 29295367Sdes fatal("%s: %s", __func__, ssh_err(r)); 30204917Sdes} 31204917Sdes 32204917SdesKey * 33204917Sdeskey_new_private(int type) 34204917Sdes{ 35295367Sdes Key *ret = NULL; 36204917Sdes 37295367Sdes if ((ret = sshkey_new_private(type)) == NULL) 38295367Sdes fatal("%s: failed", __func__); 39295367Sdes return ret; 4076262Sgreen} 4199063Sdes 4258582Skrisint 4360576Skriskey_read(Key *ret, char **cpp) 4458582Skris{ 45295367Sdes return sshkey_read(ret, cpp) == 0 ? 1 : -1; 4658582Skris} 4799063Sdes 4858582Skrisint 49126277Sdeskey_write(const Key *key, FILE *f) 5058582Skris{ 51295367Sdes return sshkey_write(key, f) == 0 ? 1 : 0; 5258582Skris} 5399063Sdes 54295367SdesKey * 55295367Sdeskey_generate(int type, u_int bits) 56207319Sdes{ 57295367Sdes int r; 58295367Sdes Key *ret = NULL; 59207319Sdes 60295367Sdes if ((r = sshkey_generate(type, bits, &ret)) != 0) 61295367Sdes fatal("%s: %s", __func__, ssh_err(r)); 62255767Sdes return ret; 63255767Sdes} 64255767Sdes 65204917Sdesvoid 66295367Sdeskey_cert_copy(const Key *from_key, Key *to_key) 67204917Sdes{ 68295367Sdes int r; 69204917Sdes 70295367Sdes if ((r = sshkey_cert_copy(from_key, to_key)) != 0) 71295367Sdes fatal("%s: %s", __func__, ssh_err(r)); 72204917Sdes} 73204917Sdes 7476262SgreenKey * 75126277Sdeskey_from_private(const Key *k) 7676262Sgreen{ 77295367Sdes int r; 78295367Sdes Key *ret = NULL; 7976262Sgreen 80295367Sdes if ((r = sshkey_from_private(k, &ret)) != 0) 81295367Sdes fatal("%s: %s", __func__, ssh_err(r)); 82204917Sdes return ret; 83204917Sdes} 84204917Sdes 85295367Sdesstatic void 86295367Sdesfatal_on_fatal_errors(int r, const char *func, int extra_fatal) 8776262Sgreen{ 88295367Sdes if (r == SSH_ERR_INTERNAL_ERROR || 89295367Sdes r == SSH_ERR_ALLOC_FAIL || 90295367Sdes (extra_fatal != 0 && r == extra_fatal)) 91295367Sdes fatal("%s: %s", func, ssh_err(r)); 9276262Sgreen} 9376262Sgreen 94262566SdesKey * 95262566Sdeskey_from_blob(const u_char *blob, u_int blen) 96262566Sdes{ 97295367Sdes int r; 98295367Sdes Key *ret = NULL; 99295367Sdes 100295367Sdes if ((r = sshkey_from_blob(blob, blen, &ret)) != 0) { 101295367Sdes fatal_on_fatal_errors(r, __func__, 0); 102295367Sdes error("%s: %s", __func__, ssh_err(r)); 103295367Sdes return NULL; 104295367Sdes } 105295367Sdes return ret; 106262566Sdes} 107262566Sdes 108295367Sdesint 109295367Sdeskey_to_blob(const Key *key, u_char **blobp, u_int *lenp) 11076262Sgreen{ 111295367Sdes u_char *blob; 112295367Sdes size_t blen; 113295367Sdes int r; 11476262Sgreen 115262566Sdes if (blobp != NULL) 116262566Sdes *blobp = NULL; 117262566Sdes if (lenp != NULL) 118262566Sdes *lenp = 0; 119295367Sdes if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { 120295367Sdes fatal_on_fatal_errors(r, __func__, 0); 121295367Sdes error("%s: %s", __func__, ssh_err(r)); 12276262Sgreen return 0; 12376262Sgreen } 124295367Sdes if (blen > INT_MAX) 125295367Sdes fatal("%s: giant len %zu", __func__, blen); 126295367Sdes if (blobp != NULL) 127295367Sdes *blobp = blob; 128106130Sdes if (lenp != NULL) 129295367Sdes *lenp = blen; 130295367Sdes return blen; 13176262Sgreen} 13276262Sgreen 13376262Sgreenint 134295367Sdeskey_sign(const Key *key, u_char **sigp, u_int *lenp, 135296781Sdes const u_char *data, u_int datalen, const char *alg) 136248619Sdes{ 137295367Sdes int r; 138295367Sdes u_char *sig; 139295367Sdes size_t siglen; 140248619Sdes 141295367Sdes if (sigp != NULL) 142295367Sdes *sigp = NULL; 143295367Sdes if (lenp != NULL) 144295367Sdes *lenp = 0; 145295367Sdes if ((r = sshkey_sign(key, &sig, &siglen, 146296781Sdes data, datalen, alg, datafellows)) != 0) { 147295367Sdes fatal_on_fatal_errors(r, __func__, 0); 148295367Sdes error("%s: %s", __func__, ssh_err(r)); 14976262Sgreen return -1; 15076262Sgreen } 151295367Sdes if (siglen > INT_MAX) 152295367Sdes fatal("%s: giant len %zu", __func__, siglen); 153295367Sdes if (sigp != NULL) 154295367Sdes *sigp = sig; 155295367Sdes if (lenp != NULL) 156295367Sdes *lenp = siglen; 157295367Sdes return 0; 15876262Sgreen} 15976262Sgreen 16076262Sgreenint 161295367Sdeskey_verify(const Key *key, const u_char *signature, u_int signaturelen, 162126277Sdes const u_char *data, u_int datalen) 16376262Sgreen{ 164295367Sdes int r; 16592559Sdes 166295367Sdes if ((r = sshkey_verify(key, signature, signaturelen, 167295367Sdes data, datalen, datafellows)) != 0) { 168295367Sdes fatal_on_fatal_errors(r, __func__, 0); 169295367Sdes error("%s: %s", __func__, ssh_err(r)); 170295367Sdes return r == SSH_ERR_SIGNATURE_INVALID ? 0 : -1; 17176262Sgreen } 172295367Sdes return 1; 17376262Sgreen} 17498684Sdes 17598684SdesKey * 176126277Sdeskey_demote(const Key *k) 17798684Sdes{ 178295367Sdes int r; 179295367Sdes Key *ret = NULL; 18098684Sdes 181295367Sdes if ((r = sshkey_demote(k, &ret)) != 0) 182295367Sdes fatal("%s: %s", __func__, ssh_err(r)); 183295367Sdes return ret; 18498684Sdes} 185204917Sdes 186204917Sdesint 187295367Sdeskey_to_certified(Key *k) 188204917Sdes{ 189295367Sdes int r; 190204917Sdes 191295367Sdes if ((r = sshkey_to_certified(k)) != 0) { 192295367Sdes fatal_on_fatal_errors(r, __func__, 0); 193295367Sdes error("%s: %s", __func__, ssh_err(r)); 194204917Sdes return -1; 195204917Sdes } 196295367Sdes return 0; 197204917Sdes} 198204917Sdes 199204917Sdesint 200204917Sdeskey_drop_cert(Key *k) 201204917Sdes{ 202295367Sdes int r; 203295367Sdes 204295367Sdes if ((r = sshkey_drop_cert(k)) != 0) { 205295367Sdes fatal_on_fatal_errors(r, __func__, 0); 206295367Sdes error("%s: %s", __func__, ssh_err(r)); 207204917Sdes return -1; 208204917Sdes } 209262566Sdes return 0; 210204917Sdes} 211204917Sdes 212204917Sdesint 213204917Sdeskey_certify(Key *k, Key *ca) 214204917Sdes{ 215295367Sdes int r; 216204917Sdes 217323124Sdes if ((r = sshkey_certify(k, ca, NULL)) != 0) { 218295367Sdes fatal_on_fatal_errors(r, __func__, 0); 219295367Sdes error("%s: %s", __func__, ssh_err(r)); 220204917Sdes return -1; 221204917Sdes } 222204917Sdes return 0; 223204917Sdes} 224204917Sdes 225204917Sdesint 226204917Sdeskey_cert_check_authority(const Key *k, int want_host, int require_principal, 227204917Sdes const char *name, const char **reason) 228204917Sdes{ 229295367Sdes int r; 230204917Sdes 231295367Sdes if ((r = sshkey_cert_check_authority(k, want_host, require_principal, 232295367Sdes name, reason)) != 0) { 233295367Sdes fatal_on_fatal_errors(r, __func__, 0); 234295367Sdes error("%s: %s", __func__, ssh_err(r)); 235204917Sdes return -1; 236204917Sdes } 237204917Sdes return 0; 238204917Sdes} 239215116Sdes 240295367Sdes#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 241215116Sdesint 242295367Sdeskey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) 243215116Sdes{ 244295367Sdes int r; 245295367Sdes 246295367Sdes if ((r = sshkey_ec_validate_public(group, public)) != 0) { 247295367Sdes fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); 248295367Sdes error("%s: %s", __func__, ssh_err(r)); 249295367Sdes return -1; 250215116Sdes } 251295367Sdes return 0; 252215116Sdes} 253221420Sdes 254221420Sdesint 255295367Sdeskey_ec_validate_private(const EC_KEY *key) 256221420Sdes{ 257295367Sdes int r; 258221420Sdes 259295367Sdes if ((r = sshkey_ec_validate_private(key)) != 0) { 260295367Sdes fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); 261295367Sdes error("%s: %s", __func__, ssh_err(r)); 262295367Sdes return -1; 263295367Sdes } 264295367Sdes return 0; 265221420Sdes} 266295367Sdes#endif /* WITH_OPENSSL */ 267221420Sdes 268295367Sdesvoid 269295367Sdeskey_private_serialize(const Key *key, struct sshbuf *b) 270221420Sdes{ 271295367Sdes int r; 272295367Sdes 273295367Sdes if ((r = sshkey_private_serialize(key, b)) != 0) 274295367Sdes fatal("%s: %s", __func__, ssh_err(r)); 275221420Sdes} 276221420Sdes 277295367SdesKey * 278295367Sdeskey_private_deserialize(struct sshbuf *blob) 279221420Sdes{ 280295367Sdes int r; 281295367Sdes Key *ret = NULL; 282295367Sdes 283295367Sdes if ((r = sshkey_private_deserialize(blob, &ret)) != 0) { 284295367Sdes fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); 285295367Sdes error("%s: %s", __func__, ssh_err(r)); 286295367Sdes return NULL; 287295367Sdes } 288295367Sdes return ret; 289221420Sdes} 290221420Sdes 291295367Sdes/* authfile.c */ 292295367Sdes 293262566Sdesint 294295367Sdeskey_save_private(Key *key, const char *filename, const char *passphrase, 295295367Sdes const char *comment, int force_new_format, const char *new_format_cipher, 296295367Sdes int new_format_rounds) 297221420Sdes{ 298295367Sdes int r; 299221420Sdes 300295367Sdes if ((r = sshkey_save_private(key, filename, passphrase, comment, 301295367Sdes force_new_format, new_format_cipher, new_format_rounds)) != 0) { 302295367Sdes fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); 303295367Sdes error("%s: %s", __func__, ssh_err(r)); 304295367Sdes return 0; 305295367Sdes } 306295367Sdes return 1; 307221420Sdes} 308221420Sdes 309221420Sdesint 310295367Sdeskey_load_file(int fd, const char *filename, struct sshbuf *blob) 311221420Sdes{ 312295367Sdes int r; 313221420Sdes 314295367Sdes if ((r = sshkey_load_file(fd, blob)) != 0) { 315295367Sdes fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); 316295367Sdes error("%s: %s", __func__, ssh_err(r)); 317295367Sdes return 0; 318221420Sdes } 319295367Sdes return 1; 320295367Sdes} 321221420Sdes 322295367SdesKey * 323295367Sdeskey_load_cert(const char *filename) 324295367Sdes{ 325295367Sdes int r; 326295367Sdes Key *ret = NULL; 327221420Sdes 328295367Sdes if ((r = sshkey_load_cert(filename, &ret)) != 0) { 329295367Sdes fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); 330295367Sdes /* Old authfile.c ignored all file errors. */ 331295367Sdes if (r == SSH_ERR_SYSTEM_ERROR) 332295367Sdes debug("%s: %s", __func__, ssh_err(r)); 333295367Sdes else 334295367Sdes error("%s: %s", __func__, ssh_err(r)); 335295367Sdes return NULL; 336221420Sdes } 337295367Sdes return ret; 338221420Sdes 339221420Sdes} 340221420Sdes 341295367SdesKey * 342295367Sdeskey_load_public(const char *filename, char **commentp) 343221420Sdes{ 344295367Sdes int r; 345295367Sdes Key *ret = NULL; 346221420Sdes 347295367Sdes if ((r = sshkey_load_public(filename, &ret, commentp)) != 0) { 348295367Sdes fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); 349295367Sdes /* Old authfile.c ignored all file errors. */ 350295367Sdes if (r == SSH_ERR_SYSTEM_ERROR) 351295367Sdes debug("%s: %s", __func__, ssh_err(r)); 352295367Sdes else 353295367Sdes error("%s: %s", __func__, ssh_err(r)); 354295367Sdes return NULL; 355221420Sdes } 356221420Sdes return ret; 357221420Sdes} 358221420Sdes 359295367SdesKey * 360295367Sdeskey_load_private(const char *path, const char *passphrase, 361295367Sdes char **commentp) 362221420Sdes{ 363295367Sdes int r; 364295367Sdes Key *ret = NULL; 365221420Sdes 366295367Sdes if ((r = sshkey_load_private(path, passphrase, &ret, commentp)) != 0) { 367295367Sdes fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); 368295367Sdes /* Old authfile.c ignored all file errors. */ 369295367Sdes if (r == SSH_ERR_SYSTEM_ERROR || 370295367Sdes r == SSH_ERR_KEY_WRONG_PASSPHRASE) 371295367Sdes debug("%s: %s", __func__, ssh_err(r)); 372295367Sdes else 373295367Sdes error("%s: %s", __func__, ssh_err(r)); 374295367Sdes return NULL; 375221420Sdes } 376295367Sdes return ret; 377221420Sdes} 378221420Sdes 379295367SdesKey * 380295367Sdeskey_load_private_cert(int type, const char *filename, const char *passphrase, 381295367Sdes int *perm_ok) 382221420Sdes{ 383295367Sdes int r; 384295367Sdes Key *ret = NULL; 385221420Sdes 386295367Sdes if ((r = sshkey_load_private_cert(type, filename, passphrase, 387295367Sdes &ret, perm_ok)) != 0) { 388295367Sdes fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); 389295367Sdes /* Old authfile.c ignored all file errors. */ 390295367Sdes if (r == SSH_ERR_SYSTEM_ERROR || 391295367Sdes r == SSH_ERR_KEY_WRONG_PASSPHRASE) 392295367Sdes debug("%s: %s", __func__, ssh_err(r)); 393295367Sdes else 394295367Sdes error("%s: %s", __func__, ssh_err(r)); 395295367Sdes return NULL; 396262566Sdes } 397295367Sdes return ret; 398262566Sdes} 399262566Sdes 400262566SdesKey * 401295367Sdeskey_load_private_type(int type, const char *filename, const char *passphrase, 402295367Sdes char **commentp, int *perm_ok) 403262566Sdes{ 404295367Sdes int r; 405295367Sdes Key *ret = NULL; 406262566Sdes 407295367Sdes if ((r = sshkey_load_private_type(type, filename, passphrase, 408295367Sdes &ret, commentp, perm_ok)) != 0) { 409295367Sdes fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); 410295367Sdes /* Old authfile.c ignored all file errors. */ 411295367Sdes if (r == SSH_ERR_SYSTEM_ERROR || 412295367Sdes (r == SSH_ERR_KEY_WRONG_PASSPHRASE)) 413295367Sdes debug("%s: %s", __func__, ssh_err(r)); 414295367Sdes else 415295367Sdes error("%s: %s", __func__, ssh_err(r)); 416262566Sdes return NULL; 417262566Sdes } 418295367Sdes return ret; 419295367Sdes} 420262566Sdes 421295367Sdesint 422295367Sdeskey_perm_ok(int fd, const char *filename) 423295367Sdes{ 424295367Sdes return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0; 425262566Sdes} 426295367Sdes 427