ssh_key pki_private_key_from_base64(ssh_session session, const char *b64_key, const char *passphrase) { BIO *mem = NULL; DSA *dsa = NULL; RSA *rsa = NULL; ssh_key key; enum ssh_keytypes_e type; /* needed for openssl initialization */ if (ssh_init() < 0) { return NULL; } type = pki_privatekey_type_from_string(b64_key); if (type == SSH_KEYTYPE_UNKNOWN) { ssh_set_error(session, SSH_FATAL, "Unknown or invalid private key."); return NULL; } mem = BIO_new_mem_buf((void*)b64_key, -1); switch (type) { case SSH_KEYTYPE_DSS: if (passphrase == NULL) { if (session->common.callbacks && session->common.callbacks->auth_function) { dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, pem_get_password, session); } else { /* openssl uses its own callback to get the passphrase here */ dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, NULL); } } else { dsa = PEM_read_bio_DSAPrivateKey(mem, NULL, NULL, (void *) passphrase); } BIO_free(mem); if (dsa == NULL) { ssh_set_error(session, SSH_FATAL, "Parsing private key: %s", ERR_error_string(ERR_get_error(), NULL)); return NULL; } break; case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA1: if (passphrase == NULL) { if (session->common.callbacks && session->common.callbacks->auth_function) { rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, pem_get_password, session); } else { /* openssl uses its own callback to get the passphrase here */ rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, NULL); } } else { rsa = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, (void *) passphrase); } BIO_free(mem); if (rsa == NULL) { ssh_set_error(session, SSH_FATAL, "Parsing private key: %s", ERR_error_string(ERR_get_error(),NULL)); return NULL; } break; case SSH_KEYTYPE_ECDSA: case SSH_KEYTYPE_UNKNOWN: BIO_free(mem); ssh_set_error(session, SSH_FATAL, "Unkown or invalid private key type %d", type); return NULL; } key = ssh_key_new(); if (key == NULL) { goto fail; } key->type = type; key->type_c = ssh_key_type_to_char(type); key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC; key->dsa = dsa; key->rsa = rsa; return key; fail: ssh_key_free(key); DSA_free(dsa); RSA_free(rsa); return NULL; }
int MAIN(int argc, char **argv) { #ifndef OPENSSL_NO_ENGINE ENGINE *e = NULL; #endif int ret=1; DSA *dsa=NULL; int i,badops=0; const EVP_CIPHER *enc=NULL; BIO *in=NULL,*out=NULL; int informat,outformat,text=0,noout=0; int pubin = 0, pubout = 0; char *infile,*outfile,*prog; #ifndef OPENSSL_NO_ENGINE char *engine; #endif char *passargin = NULL, *passargout = NULL; char *passin = NULL, *passout = NULL; int modulus=0; apps_startup(); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; #ifndef OPENSSL_NO_ENGINE engine=NULL; #endif infile=NULL; outfile=NULL; informat=FORMAT_PEM; outformat=FORMAT_PEM; prog=argv[0]; argc--; argv++; while (argc >= 1) { if (strcmp(*argv,"-inform") == 0) { if (--argc < 1) goto bad; informat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-outform") == 0) { if (--argc < 1) goto bad; outformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } else if (strcmp(*argv,"-passin") == 0) { if (--argc < 1) goto bad; passargin= *(++argv); } else if (strcmp(*argv,"-passout") == 0) { if (--argc < 1) goto bad; passargout= *(++argv); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } #endif else if (strcmp(*argv,"-noout") == 0) noout=1; else if (strcmp(*argv,"-text") == 0) text=1; else if (strcmp(*argv,"-modulus") == 0) modulus=1; else if (strcmp(*argv,"-pubin") == 0) pubin=1; else if (strcmp(*argv,"-pubout") == 0) pubout=1; else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL) { BIO_printf(bio_err,"unknown option %s\n",*argv); badops=1; break; } argc--; argv++; } if (badops) { bad: BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog); BIO_printf(bio_err,"where options are\n"); BIO_printf(bio_err," -inform arg input format - DER or PEM\n"); BIO_printf(bio_err," -outform arg output format - DER or PEM\n"); BIO_printf(bio_err," -in arg input file\n"); BIO_printf(bio_err," -passin arg input file pass phrase source\n"); BIO_printf(bio_err," -out arg output file\n"); BIO_printf(bio_err," -passout arg output file pass phrase source\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf(bio_err," -des encrypt PEM output with cbc des\n"); BIO_printf(bio_err," -des3 encrypt PEM output with ede cbc des using 168 bit key\n"); #ifndef OPENSSL_NO_IDEA BIO_printf(bio_err," -idea encrypt PEM output with cbc idea\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf(bio_err," -aes128, -aes192, -aes256\n"); BIO_printf(bio_err," encrypt PEM output with cbc aes\n"); #endif BIO_printf(bio_err," -text print the key in text\n"); BIO_printf(bio_err," -noout don't print key out\n"); BIO_printf(bio_err," -modulus print the DSA public value\n"); goto end; } ERR_load_crypto_strings(); #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } in=BIO_new(BIO_s_file()); out=BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } if (infile == NULL) BIO_set_fp(in,stdin,BIO_NOCLOSE); else { if (BIO_read_filename(in,infile) <= 0) { perror(infile); goto end; } } BIO_printf(bio_err,"read DSA key\n"); if (informat == FORMAT_ASN1) { if(pubin) dsa=d2i_DSA_PUBKEY_bio(in,NULL); else dsa=d2i_DSAPrivateKey_bio(in,NULL); } else if (informat == FORMAT_PEM) { if(pubin) dsa=PEM_read_bio_DSA_PUBKEY(in,NULL, NULL, NULL); else dsa=PEM_read_bio_DSAPrivateKey(in,NULL,NULL,passin); } else { BIO_printf(bio_err,"bad input format specified for key\n"); goto end; } if (dsa == NULL) { BIO_printf(bio_err,"unable to load Key\n"); ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outfile) <= 0) { perror(outfile); goto end; } } if (text) if (!DSA_print(out,dsa,0)) { perror(outfile); ERR_print_errors(bio_err); goto end; } if (modulus) { fprintf(stdout,"Public Key="); BN_print(out,dsa->pub_key); fprintf(stdout,"\n"); } if (noout) goto end; BIO_printf(bio_err,"writing DSA key\n"); if (outformat == FORMAT_ASN1) { if(pubin || pubout) i=i2d_DSA_PUBKEY_bio(out,dsa); else i=i2d_DSAPrivateKey_bio(out,dsa); } else if (outformat == FORMAT_PEM) { if(pubin || pubout) i=PEM_write_bio_DSA_PUBKEY(out,dsa); else i=PEM_write_bio_DSAPrivateKey(out,dsa,enc, NULL,0,NULL, passout); } else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err,"unable to write private key\n"); ERR_print_errors(bio_err); } else ret=0; end: if(in != NULL) BIO_free(in); if(out != NULL) BIO_free_all(out); if(dsa != NULL) DSA_free(dsa); if(passin) OPENSSL_free(passin); if(passout) OPENSSL_free(passout); apps_shutdown(); OPENSSL_EXIT(ret); }
inline dsa_key dsa_key::from_private_key(bio::bio_ptr bio, pem_passphrase_callback_type callback, void* callback_arg) { return take_ownership(PEM_read_bio_DSAPrivateKey(bio.raw(), NULL, callback, callback_arg)); }
ssh_key* ssh_key_alloc(char* data, int length, char* passphrase) { ssh_key* key; BIO* key_bio; char* public_key; char* pos; /* Create BIO for reading key from memory */ key_bio = BIO_new_mem_buf(data, length); /* If RSA key, load RSA */ if (length > sizeof(SSH_RSA_KEY_HEADER)-1 && memcmp(SSH_RSA_KEY_HEADER, data, sizeof(SSH_RSA_KEY_HEADER)-1) == 0) { RSA* rsa_key; /* Read key */ rsa_key = PEM_read_bio_RSAPrivateKey(key_bio, NULL, NULL, passphrase); if (rsa_key == NULL) return NULL; /* Allocate key */ key = malloc(sizeof(ssh_key)); key->rsa = rsa_key; /* Set type */ key->type = SSH_KEY_RSA; /* Allocate space for public key */ public_key = malloc(4096); pos = public_key; /* Derive public key */ buffer_write_string(&pos, "ssh-rsa", sizeof("ssh-rsa")-1); buffer_write_bignum(&pos, rsa_key->e); buffer_write_bignum(&pos, rsa_key->n); /* Save public key to structure */ key->public_key = public_key; key->public_key_length = pos - public_key; } /* If DSA key, load DSA */ else if (length > sizeof(SSH_DSA_KEY_HEADER)-1 && memcmp(SSH_DSA_KEY_HEADER, data, sizeof(SSH_DSA_KEY_HEADER)-1) == 0) { DSA* dsa_key; /* Read key */ dsa_key = PEM_read_bio_DSAPrivateKey(key_bio, NULL, NULL, passphrase); if (dsa_key == NULL) return NULL; /* Allocate key */ key = malloc(sizeof(ssh_key)); key->dsa = dsa_key; /* Set type */ key->type = SSH_KEY_DSA; /* Allocate space for public key */ public_key = malloc(4096); pos = public_key; /* Derive public key */ buffer_write_string(&pos, "ssh-dss", sizeof("ssh-dss")-1); buffer_write_bignum(&pos, dsa_key->p); buffer_write_bignum(&pos, dsa_key->q); buffer_write_bignum(&pos, dsa_key->g); buffer_write_bignum(&pos, dsa_key->pub_key); /* Save public key to structure */ key->public_key = public_key; key->public_key_length = pos - public_key; } /* Otherwise, unsupported type */ else { BIO_free(key_bio); return NULL; } /* Copy private key to structure */ key->private_key_length = length; key->private_key = malloc(length); memcpy(key->private_key, data, length); BIO_free(key_bio); return key; }
int FuzzerTestOneInput(const uint8_t *buf, size_t len) { SSL *server; BIO *in; BIO *out; #if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DSA) BIO *bio_buf; #endif SSL_CTX *ctx; int ret; RSA *privkey; const uint8_t *bufp; EVP_PKEY *pkey; X509 *cert; #ifndef OPENSSL_NO_EC EC_KEY *ecdsakey = NULL; #endif #ifndef OPENSSL_NO_DSA DSA *dsakey = NULL; #endif uint8_t opt; if (len < 2) return 0; /* * TODO: use the ossltest engine (optionally?) to disable crypto checks. */ /* This only fuzzes the initial flow from the client so far. */ ctx = SSL_CTX_new(SSLv23_method()); ret = SSL_CTX_set_min_proto_version(ctx, 0); OPENSSL_assert(ret == 1); ret = SSL_CTX_set_cipher_list(ctx, "ALL:eNULL:@SECLEVEL=0"); OPENSSL_assert(ret == 1); /* RSA */ bufp = kRSAPrivateKeyDER; privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER)); OPENSSL_assert(privkey != NULL); pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, privkey); ret = SSL_CTX_use_PrivateKey(ctx, pkey); OPENSSL_assert(ret == 1); EVP_PKEY_free(pkey); bufp = kCertificateDER; cert = d2i_X509(NULL, &bufp, sizeof(kCertificateDER)); OPENSSL_assert(cert != NULL); ret = SSL_CTX_use_certificate(ctx, cert); OPENSSL_assert(ret == 1); X509_free(cert); #ifndef OPENSSL_NO_EC /* ECDSA */ bio_buf = BIO_new(BIO_s_mem()); OPENSSL_assert((size_t)BIO_write(bio_buf, ECDSAPrivateKeyPEM, sizeof(ECDSAPrivateKeyPEM)) == sizeof(ECDSAPrivateKeyPEM)); ecdsakey = PEM_read_bio_ECPrivateKey(bio_buf, NULL, NULL, NULL); ERR_print_errors_fp(stderr); OPENSSL_assert(ecdsakey != NULL); BIO_free(bio_buf); pkey = EVP_PKEY_new(); EVP_PKEY_assign_EC_KEY(pkey, ecdsakey); ret = SSL_CTX_use_PrivateKey(ctx, pkey); OPENSSL_assert(ret == 1); EVP_PKEY_free(pkey); bio_buf = BIO_new(BIO_s_mem()); OPENSSL_assert((size_t)BIO_write(bio_buf, ECDSACertPEM, sizeof(ECDSACertPEM)) == sizeof(ECDSACertPEM)); cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); OPENSSL_assert(cert != NULL); BIO_free(bio_buf); ret = SSL_CTX_use_certificate(ctx, cert); OPENSSL_assert(ret == 1); X509_free(cert); #endif #ifndef OPENSSL_NO_DSA /* DSA */ bio_buf = BIO_new(BIO_s_mem()); OPENSSL_assert((size_t)BIO_write(bio_buf, DSAPrivateKeyPEM, sizeof(DSAPrivateKeyPEM)) == sizeof(DSAPrivateKeyPEM)); dsakey = PEM_read_bio_DSAPrivateKey(bio_buf, NULL, NULL, NULL); ERR_print_errors_fp(stderr); OPENSSL_assert(dsakey != NULL); BIO_free(bio_buf); pkey = EVP_PKEY_new(); EVP_PKEY_assign_DSA(pkey, dsakey); ret = SSL_CTX_use_PrivateKey(ctx, pkey); OPENSSL_assert(ret == 1); EVP_PKEY_free(pkey); bio_buf = BIO_new(BIO_s_mem()); OPENSSL_assert((size_t)BIO_write(bio_buf, DSACertPEM, sizeof(DSACertPEM)) == sizeof(DSACertPEM)); cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); OPENSSL_assert(cert != NULL); BIO_free(bio_buf); ret = SSL_CTX_use_certificate(ctx, cert); OPENSSL_assert(ret == 1); X509_free(cert); #endif /* TODO: Set up support for SRP and PSK */ server = SSL_new(ctx); in = BIO_new(BIO_s_mem()); out = BIO_new(BIO_s_mem()); SSL_set_bio(server, in, out); SSL_set_accept_state(server); opt = (uint8_t)buf[len-1]; len--; OPENSSL_assert((size_t)BIO_write(in, buf, len) == len); if ((opt & 0x01) != 0) { do { char early_buf[16384]; size_t early_len; ret = SSL_read_early_data(server, early_buf, sizeof(early_buf), &early_len); if (ret != SSL_READ_EARLY_DATA_SUCCESS) break; } while (1); } if (SSL_do_handshake(server) == 1) { /* Keep reading application data until error or EOF. */ uint8_t tmp[1024]; for (;;) { if (SSL_read(server, tmp, sizeof(tmp)) <= 0) { break; } } } SSL_free(server); ERR_clear_error(); SSL_CTX_free(ctx); return 0; }