/* gcc -Wall ssh-fmt-crash.c -lcrypto -lssl -o ssh-fmt-crash */ #include #include #include #include #include #include #include static void process_file(const char *filename, const char* password) { FILE *keyfile; BIO *bp; char *nm = NULL, *header = NULL; unsigned char *data = NULL; EVP_CIPHER_INFO cipher; EVP_PKEY pk; long len; DSA *dsapkc = NULL; RSA *rsapkc = NULL; const char unsigned *dc; if (!(keyfile = fopen(filename, "rb"))) { fprintf(stderr, "! %s : %s\n", filename, strerror(errno)); return; } bp = BIO_new(BIO_s_file()); if(!bp) { fprintf(stderr, "OpenSSL BIO allocation failure\n"); return; } if(!BIO_read_filename(bp, filename)) { fprintf(stderr, "OpenSSL BIO_read_filename failure\n"); ERR_print_errors_fp(stderr); return; } for (;;) { if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) { /* ERR_print_errors_fp(stderr); */ fprintf(stderr, "! %s : %s\n", filename, "input keyfile validation failed"); goto out; } } if(!nm) { fprintf(stderr, "! %s : %s\n", filename, "input keyfile validation failed"); goto out; } if (!strcmp(nm, PEM_STRING_DSA)) { pk.save_type = EVP_PKEY_DSA; break; } if (!strcmp(nm, PEM_STRING_RSA)) { pk.save_type = EVP_PKEY_RSA; break; } OPENSSL_free(nm); OPENSSL_free(header); OPENSSL_free(data); BIO_free(bp); } if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) { ERR_print_errors_fp(stderr); return; } /* check if key has no password */ dc = data; if (PEM_do_header(&cipher, data, &len, NULL, (char *)password)) { if (pk.save_type == EVP_PKEY_DSA) { if ((dsapkc = d2i_DSAPrivateKey(NULL, &dc, len)) != NULL) { printf("OK\n"); DSA_free(dsapkc); goto out; } } else if (pk.save_type == EVP_PKEY_RSA) { if ((rsapkc = d2i_RSAPrivateKey(NULL, &dc, len)) != NULL) { printf("OK\n"); RSA_free(rsapkc); goto out; } } } printf("Wrong Password!\n"); out: fclose(keyfile); if(bp) BIO_free(bp); } int main(int argc, char **argv) { int i; SSL_load_error_strings(); SSL_library_init(); OpenSSL_add_all_algorithms(); if (argc < 3) { printf("Usage: %s [password] [key files]\n", argv[0]); return 0; } for(i = 2; i < argc; i++) { printf("%s : ", argv[i]); process_file(argv[i], argv[1]); } return 0; }