static int file_read_pem(BIO *bp, char **pem_name, char **pem_header, unsigned char **data, long *len, const UI_METHOD *ui_method, void *ui_data, int secure) { int i = secure ? PEM_read_bio_ex(bp, pem_name, pem_header, data, len, PEM_FLAG_SECURE | PEM_FLAG_EAY_COMPATIBLE) : PEM_read_bio(bp, pem_name, pem_header, data, len); if (i <= 0) return 0; /* * 10 is the number of characters in "Proc-Type:", which * PEM_get_EVP_CIPHER_INFO() requires to be present. * If the PEM header has less characters than that, it's * not worth spending cycles on it. */ if (strlen(*pem_header) > 10) { EVP_CIPHER_INFO cipher; struct pem_pass_data pass_data; if (!PEM_get_EVP_CIPHER_INFO(*pem_header, &cipher) || !file_fill_pem_pass_data(&pass_data, "PEM", ui_method, ui_data) || !PEM_do_header(&cipher, *data, len, file_get_pem_pass, &pass_data)) { return 0; } } return 1; }
void openssl_rsa_pemkey() { long len; BIGNUM *bne; BIO *ins, *outs; RSA *r, *read; char *name, *head; unsigned char *data; const EVP_CIPHER *enc; EVP_CIPHER_INFO cipher; OpenSSL_add_all_algorithms(); bne = BN_new(); BN_set_word(bne, RSA_3); r = RSA_new(); RSA_generate_key_ex(r, LINE_LEN, bne, NULL); enc = EVP_des_ede3_ofb(); outs = BIO_new_file("/tmp/pri.pem", "w"); PEM_write_bio_RSAPrivateKey(outs, r, enc, NULL, 0, NULL, "beike2012"); BIO_free(outs); outs = BIO_new_file("/tmp/pub.pem", "w"); PEM_write_bio_RSAPublicKey(outs, r); BIO_free(outs); ins = BIO_new_file("/tmp/pri.pem", "rb"); r = RSA_new(); read = PEM_read_bio_RSAPrivateKey(ins, &r, NULL, "beike2012"); if (read->d == NULL) { printf("PEM_read_bio_RSAPrivateKey err!\n"); return; } printf("\nEVP_CIPHER_INFO:\n"); while (1) { if (PEM_read_bio(ins, &name, &head, &data, &len) == 0) break; if (strlen(head) > 0) { PEM_get_EVP_CIPHER_INFO(head, &cipher); if (PEM_do_header(&cipher, data, &len, NULL, NULL) == 0) return; printf("name=%s, head=%s, data=%s\n", name, head, data); } OPENSSL_free(name); OPENSSL_free(head); OPENSSL_free(data); } RSA_free(read); BIO_free(ins); }
int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp, pem_password_cb *cb, void *u) { EVP_CIPHER_INFO cipher; char *nm = NULL, *header = NULL; unsigned char *data = NULL; long len; int ret = 0; for (;;) { if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) ERR_asprintf_error_data("Expecting: %s", name); return 0; } if (check_pem(nm, name)) break; free(nm); free(header); free(data); } if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) goto err; if (!PEM_do_header(&cipher, data, &len, cb, u)) goto err; *pdata = data; *plen = len; if (pnm) *pnm = nm; ret = 1; err: if (!ret || !pnm) free(nm); free(header); if (!ret) free(data); return ret; }
static int pem_bytes_read_bio_flags(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp, pem_password_cb *cb, void *u, unsigned int flags) { EVP_CIPHER_INFO cipher; char *nm = NULL, *header = NULL; unsigned char *data = NULL; long len = 0; int ret = 0; do { pem_free(nm, flags, 0); pem_free(header, flags, 0); pem_free(data, flags, len); if (!PEM_read_bio_ex(bp, &nm, &header, &data, &len, flags)) { if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) ERR_add_error_data(2, "Expecting: ", name); return 0; } } while (!check_pem(nm, name)); if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) goto err; if (!PEM_do_header(&cipher, data, &len, cb, u)) goto err; *pdata = data; *plen = len; if (pnm != NULL) *pnm = nm; ret = 1; err: if (!ret || pnm == NULL) pem_free(nm, flags, 0); pem_free(header, flags, 0); if (!ret) pem_free(data, flags, len); return ret; }
static void process_file(const char *filename) { FILE *keyfile; int i, count; unsigned char buffer[LINE_BUFFER_SIZE]; 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; } /* verify input files using OpenSSL */ 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; } /* PEM_bytes_read_bio function in crypto/pem/pem_lib.c * check_pem function in crypto/pem/pem_lib.c */ 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; } /* only PEM encoded DSA and RSA private keys are supported. */ 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 *) "")) { if (pk.save_type == EVP_PKEY_DSA) { if ((dsapkc = d2i_DSAPrivateKey(NULL, &dc, len)) != NULL) { fprintf(stderr, "%s has no password!\n", filename); DSA_free(dsapkc); goto out; } } else if (pk.save_type == EVP_PKEY_RSA) { if ((rsapkc = d2i_RSAPrivateKey(NULL, &dc, len)) != NULL) { fprintf(stderr, "%s has no password!\n", filename); RSA_free(rsapkc); goto out; } } } /* key has been verified */ count = fread(buffer, 1, LINE_BUFFER_SIZE, keyfile); printf("%s:$ssh2$", basename(filename)); for (i = 0; i < count; i++) { printf("%c%c", itoa16[ARCH_INDEX(buffer[i] >> 4)], itoa16[ARCH_INDEX(buffer[i] & 0x0f)]); } printf("*%d\n", count); out: fclose(keyfile); if(bp) BIO_free(bp); }