Loading CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,10 @@ Changes between 0.9.8b and 0.9.9 [xx XXX xxxx] *) Replace the algorithm specific calls to genrate keys in "req" with the new API. [Steve Henson] *) Update PKCS#7 enveloped data routines to use new API. This is now supported by any public key method supporting the encrypt operation. A ctrl is added to allow the public key algorithm to examine or modify Loading apps/req.c +220 −179 Original line number Diff line number Diff line Loading @@ -141,22 +141,18 @@ static int add_attribute_object(X509_REQ *req, char *text, const char *def, int n_max, unsigned long chtype); static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value, int nid,int n_min,int n_max, unsigned long chtype, int mval); #ifndef OPENSSL_NO_RSA static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb); #endif static int genpkey_cb(EVP_PKEY_CTX *ctx); static int req_check_len(int len,int n_min,int n_max); static int check_end(const char *str, const char *end); static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, long *pkeylen, const char **palgnam, ENGINE *e); #ifndef MONOLITH static char *default_config_file=NULL; #endif static CONF *req_conf=NULL; static int batch=0; #define TYPE_RSA 1 #define TYPE_DSA 2 #define TYPE_DH 3 #define TYPE_EC 4 int MAIN(int, char **); int MAIN(int argc, char **argv) Loading @@ -172,8 +168,10 @@ int MAIN(int argc, char **argv) int ex=1,x509=0,days=30; X509 *x509ss=NULL; X509_REQ *req=NULL; EVP_PKEY_CTX *genctx = NULL; const char *keyalgstr; EVP_PKEY *pkey=NULL; int i=0,badops=0,newreq=0,verbose=0,pkey_type=TYPE_RSA; int i=0,badops=0,newreq=0,verbose=0,pkey_type=EVP_PKEY_RSA; long newkey = -1; BIO *in=NULL,*out=NULL; int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM; Loading Loading @@ -292,125 +290,33 @@ int MAIN(int argc, char **argv) } else if (strcmp(*argv,"-newkey") == 0) { int is_numeric; if (--argc < 1) goto bad; p= *(++argv); is_numeric = p[0] >= '0' && p[0] <= '9'; if (strncmp("rsa:",p,4) == 0 || is_numeric) { pkey_type=TYPE_RSA; if(!is_numeric) p+=4; newkey= atoi(p); } else #ifndef OPENSSL_NO_DSA if (strncmp("dsa:",p,4) == 0) { X509 *xtmp=NULL; EVP_PKEY *dtmp; if (--argc < 1) goto bad; pkey_type=TYPE_DSA; p+=4; if ((in=BIO_new_file(p,"r")) == NULL) { perror(p); goto end; } if ((dsa_params=PEM_read_bio_DSAparams(in,NULL,NULL,NULL)) == NULL) { ERR_clear_error(); (void)BIO_reset(in); if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) { BIO_printf(bio_err,"unable to load DSA parameters from file\n"); goto end; } genctx = set_keygen_ctx(bio_err, *(++argv), &newkey, &keyalgstr, e); if ((dtmp=X509_get_pubkey(xtmp)) == NULL) goto end; if (dtmp->type == EVP_PKEY_DSA) dsa_params=DSAparams_dup(dtmp->pkey.dsa); EVP_PKEY_free(dtmp); X509_free(xtmp); if (dsa_params == NULL) { BIO_printf(bio_err,"Certificate does not contain DSA parameters\n"); goto end; } } BIO_free(in); in=NULL; newkey=BN_num_bits(dsa_params->p); } else #endif #ifndef OPENSSL_NO_ECDSA if (strncmp("ec:",p,3) == 0) { X509 *xtmp=NULL; EVP_PKEY *dtmp; EC_GROUP *group; if (!genctx) goto bad; pkey_type=TYPE_EC; p+=3; if ((in=BIO_new_file(p,"r")) == NULL) { perror(p); goto end; newreq=1; } if ((ec_params = EC_KEY_new()) == NULL) goto end; group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); if (group == NULL) else if (strcmp(*argv,"-pkeyopt") == 0) { EC_KEY_free(ec_params); ERR_clear_error(); (void)BIO_reset(in); if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) { BIO_printf(bio_err,"unable to load EC parameters from file\n"); goto end; } if ((dtmp=X509_get_pubkey(xtmp))==NULL) goto end; if (dtmp->type == EVP_PKEY_EC) ec_params = EC_KEY_dup(dtmp->pkey.ec); EVP_PKEY_free(dtmp); X509_free(xtmp); if (ec_params == NULL) if (--argc < 1) goto bad; if (!genctx) { BIO_printf(bio_err,"Certificate does not contain EC parameters\n"); goto end; } BIO_puts(bio_err, "No keytype specified\n"); goto bad; } else else if (pkey_ctrl_string(genctx, *(++argv)) <= 0) { if (EC_KEY_set_group(ec_params, group) == 0) BIO_puts(bio_err, "parameter setting error\n"); ERR_print_errors(bio_err); goto end; EC_GROUP_free(group); } BIO_free(in); in=NULL; newkey = EC_GROUP_get_degree(EC_KEY_get0_group(ec_params)); } else #endif #ifndef OPENSSL_NO_DH if (strncmp("dh:",p,4) == 0) { pkey_type=TYPE_DH; p+=3; } else #endif { goto bad; } newreq=1; } else if (strcmp(*argv,"-batch") == 0) batch=1; Loading Loading @@ -731,9 +637,6 @@ bad: if (newreq && (pkey == NULL)) { #ifndef OPENSSL_NO_RSA BN_GENCB cb; #endif char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE"); if (randfile == NULL) ERR_clear_error(); Loading @@ -747,53 +650,35 @@ bad: newkey=DEFAULT_KEY_LENGTH; } if (newkey < MIN_KEY_LENGTH && (pkey_type == TYPE_RSA || pkey_type == TYPE_DSA)) if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) { BIO_printf(bio_err,"private key length is too short,\n"); BIO_printf(bio_err,"it needs to be at least %d bits, not %ld\n",MIN_KEY_LENGTH,newkey); goto end; } BIO_printf(bio_err,"Generating a %ld bit %s private key\n", newkey,(pkey_type == TYPE_RSA)?"RSA": (pkey_type == TYPE_DSA)?"DSA":"EC"); if ((pkey=EVP_PKEY_new()) == NULL) goto end; #ifndef OPENSSL_NO_RSA BN_GENCB_set(&cb, req_cb, bio_err); if (pkey_type == TYPE_RSA) { RSA *rsa = RSA_new(); BIGNUM *bn = BN_new(); if(!bn || !rsa || !BN_set_word(bn, 0x10001) || !RSA_generate_key_ex(rsa, newkey, bn, &cb) || !EVP_PKEY_assign_RSA(pkey, rsa)) if (!genctx) { if(bn) BN_free(bn); if(rsa) RSA_free(rsa); genctx = set_keygen_ctx(bio_err, NULL, &newkey, &keyalgstr, e); if (!genctx) goto end; } BN_free(bn); } else #endif #ifndef OPENSSL_NO_DSA if (pkey_type == TYPE_DSA) { if (!DSA_generate_key(dsa_params)) goto end; if (!EVP_PKEY_assign_DSA(pkey,dsa_params)) goto end; dsa_params=NULL; } #endif #ifndef OPENSSL_NO_ECDSA if (pkey_type == TYPE_EC) BIO_printf(bio_err,"Generating a %ld bit %s private key\n", newkey, keyalgstr); EVP_PKEY_CTX_set_cb(genctx, genpkey_cb); EVP_PKEY_CTX_set_app_data(genctx, bio_err); if (EVP_PKEY_keygen(genctx, &pkey) <= 0) { if (!EC_KEY_generate_key(ec_params)) goto end; if (!EVP_PKEY_assign_EC_KEY(pkey, ec_params)) BIO_puts(bio_err, "Error Generating Key\n"); goto end; ec_params = NULL; } #endif EVP_PKEY_CTX_free(genctx); genctx = NULL; app_RAND_write_file(randfile, bio_err); Loading Loading @@ -959,8 +844,11 @@ loop: } if (!(i=X509_sign(x509ss,pkey,digest))) { ERR_print_errors(bio_err); goto end; } } else { X509V3_CTX ext_ctx; Loading @@ -980,9 +868,12 @@ loop: goto end; } if (!(i=X509_REQ_sign(req,pkey,digest))) { ERR_print_errors(bio_err); goto end; } } } if (subj && x509) { Loading Loading @@ -1117,7 +1008,7 @@ loop: } fprintf(stdout,"Modulus="); #ifndef OPENSSL_NO_RSA if (tpubkey->type == EVP_PKEY_RSA) if (EVP_PKEY_base_id(tpubkey)) BN_print(out,tpubkey->pkey.rsa->n); else #endif Loading Loading @@ -1173,6 +1064,8 @@ end: BIO_free(in); BIO_free_all(out); EVP_PKEY_free(pkey); if (genctx) EVP_PKEY_CTX_free(genctx); X509_REQ_free(req); X509_free(x509ss); ASN1_INTEGER_free(serial); Loading Loading @@ -1631,24 +1524,6 @@ err: return(0); } #ifndef OPENSSL_NO_RSA static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb) { char c='*'; if (p == 0) c='.'; if (p == 1) c='+'; if (p == 2) c='*'; if (p == 3) c='\n'; BIO_write(cb->arg,&c,1); (void)BIO_flush(cb->arg); #ifdef LINT p=n; #endif return 1; } #endif static int req_check_len(int len, int n_min, int n_max) { if ((n_min > 0) && (len < n_min)) Loading @@ -1675,3 +1550,169 @@ static int check_end(const char *str, const char *end) tmp = str + slen - elen; return strcmp(tmp, end); } static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, long *pkeylen, const char **palgnam, ENGINE *e) { EVP_PKEY_CTX *gctx = NULL; EVP_PKEY *param = NULL; long keylen = -1; int pkey_type = -1; BIO *pbio = NULL; const char *paramfile = NULL; if (gstr == NULL) { pkey_type = EVP_PKEY_RSA; keylen = *pkeylen; } else if (gstr[0] >= '0' && gstr[0] <= '9') { pkey_type = EVP_PKEY_RSA; keylen = atol(gstr); *pkeylen = keylen; } else if (!strncmp(gstr, "param:", 6)) paramfile = gstr + 6; else { const char *p = strchr(gstr, ':'); int len; const EVP_PKEY_ASN1_METHOD *ameth; if (p) len = p - gstr; else len = strlen(gstr); ameth = EVP_PKEY_asn1_find_str(gstr, len); if (!ameth) { BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr); return NULL; } EVP_PKEY_asn1_get0_info(NULL, &pkey_type, NULL, NULL, NULL, ameth); if (pkey_type == EVP_PKEY_RSA) { if (p) { keylen = atol(p + 1); *pkeylen = keylen; } } else if (p) paramfile = p + 1; } if (paramfile) { pbio = BIO_new_file(paramfile, "r"); if (!pbio) { BIO_printf(err, "Can't open parameter file %s\n", paramfile); return NULL; } param = PEM_read_bio_Parameters(pbio, NULL); if (!param) { X509 *x; BIO_reset(pbio); x = PEM_read_bio_X509(pbio, NULL, NULL, NULL); if (x) { param = X509_get_pubkey(x); X509_free(x); } } BIO_free(pbio); if (!param) { BIO_printf(err, "Error reading parameter file %s\n", paramfile); return NULL; } if (pkey_type == -1) pkey_type = EVP_PKEY_id(param); else if (pkey_type != EVP_PKEY_base_id(param)) { BIO_printf(err, "Key Type does not match parameters\n"); EVP_PKEY_free(param); return NULL; } } if (palgnam) { const EVP_PKEY_ASN1_METHOD *ameth; ameth = EVP_PKEY_asn1_find(pkey_type); if (!ameth) { BIO_puts(err, "Internal error: can't find key algorithm\n"); return NULL; } EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, palgnam, ameth); } if (param) { gctx = EVP_PKEY_CTX_new(param, e); *pkeylen = EVP_PKEY_bits(param); EVP_PKEY_free(param); } else gctx = EVP_PKEY_CTX_new_id(pkey_type, e); if (!gctx) { BIO_puts(err, "Error allocating keygen context\n"); ERR_print_errors(err); return NULL; } if (EVP_PKEY_keygen_init(gctx) <= 0) { BIO_puts(err, "Error initializing keygen context\n"); ERR_print_errors(err); return NULL; } if ((pkey_type == EVP_PKEY_RSA) && (keylen != -1)) { if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) { BIO_puts(err, "Error setting RSA keysize\n"); ERR_print_errors(err); EVP_PKEY_CTX_free(gctx); return NULL; } } return gctx; } static int genpkey_cb(EVP_PKEY_CTX *ctx) { char c='*'; BIO *b = EVP_PKEY_CTX_get_app_data(ctx); int p; p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); if (p == 0) c='.'; if (p == 1) c='+'; if (p == 2) c='*'; if (p == 3) c='\n'; BIO_write(b,&c,1); (void)BIO_flush(b); #ifdef LINT p=n; #endif return 1; } Loading
CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,10 @@ Changes between 0.9.8b and 0.9.9 [xx XXX xxxx] *) Replace the algorithm specific calls to genrate keys in "req" with the new API. [Steve Henson] *) Update PKCS#7 enveloped data routines to use new API. This is now supported by any public key method supporting the encrypt operation. A ctrl is added to allow the public key algorithm to examine or modify Loading
apps/req.c +220 −179 Original line number Diff line number Diff line Loading @@ -141,22 +141,18 @@ static int add_attribute_object(X509_REQ *req, char *text, const char *def, int n_max, unsigned long chtype); static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value, int nid,int n_min,int n_max, unsigned long chtype, int mval); #ifndef OPENSSL_NO_RSA static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb); #endif static int genpkey_cb(EVP_PKEY_CTX *ctx); static int req_check_len(int len,int n_min,int n_max); static int check_end(const char *str, const char *end); static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, long *pkeylen, const char **palgnam, ENGINE *e); #ifndef MONOLITH static char *default_config_file=NULL; #endif static CONF *req_conf=NULL; static int batch=0; #define TYPE_RSA 1 #define TYPE_DSA 2 #define TYPE_DH 3 #define TYPE_EC 4 int MAIN(int, char **); int MAIN(int argc, char **argv) Loading @@ -172,8 +168,10 @@ int MAIN(int argc, char **argv) int ex=1,x509=0,days=30; X509 *x509ss=NULL; X509_REQ *req=NULL; EVP_PKEY_CTX *genctx = NULL; const char *keyalgstr; EVP_PKEY *pkey=NULL; int i=0,badops=0,newreq=0,verbose=0,pkey_type=TYPE_RSA; int i=0,badops=0,newreq=0,verbose=0,pkey_type=EVP_PKEY_RSA; long newkey = -1; BIO *in=NULL,*out=NULL; int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM; Loading Loading @@ -292,125 +290,33 @@ int MAIN(int argc, char **argv) } else if (strcmp(*argv,"-newkey") == 0) { int is_numeric; if (--argc < 1) goto bad; p= *(++argv); is_numeric = p[0] >= '0' && p[0] <= '9'; if (strncmp("rsa:",p,4) == 0 || is_numeric) { pkey_type=TYPE_RSA; if(!is_numeric) p+=4; newkey= atoi(p); } else #ifndef OPENSSL_NO_DSA if (strncmp("dsa:",p,4) == 0) { X509 *xtmp=NULL; EVP_PKEY *dtmp; if (--argc < 1) goto bad; pkey_type=TYPE_DSA; p+=4; if ((in=BIO_new_file(p,"r")) == NULL) { perror(p); goto end; } if ((dsa_params=PEM_read_bio_DSAparams(in,NULL,NULL,NULL)) == NULL) { ERR_clear_error(); (void)BIO_reset(in); if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) { BIO_printf(bio_err,"unable to load DSA parameters from file\n"); goto end; } genctx = set_keygen_ctx(bio_err, *(++argv), &newkey, &keyalgstr, e); if ((dtmp=X509_get_pubkey(xtmp)) == NULL) goto end; if (dtmp->type == EVP_PKEY_DSA) dsa_params=DSAparams_dup(dtmp->pkey.dsa); EVP_PKEY_free(dtmp); X509_free(xtmp); if (dsa_params == NULL) { BIO_printf(bio_err,"Certificate does not contain DSA parameters\n"); goto end; } } BIO_free(in); in=NULL; newkey=BN_num_bits(dsa_params->p); } else #endif #ifndef OPENSSL_NO_ECDSA if (strncmp("ec:",p,3) == 0) { X509 *xtmp=NULL; EVP_PKEY *dtmp; EC_GROUP *group; if (!genctx) goto bad; pkey_type=TYPE_EC; p+=3; if ((in=BIO_new_file(p,"r")) == NULL) { perror(p); goto end; newreq=1; } if ((ec_params = EC_KEY_new()) == NULL) goto end; group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); if (group == NULL) else if (strcmp(*argv,"-pkeyopt") == 0) { EC_KEY_free(ec_params); ERR_clear_error(); (void)BIO_reset(in); if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) { BIO_printf(bio_err,"unable to load EC parameters from file\n"); goto end; } if ((dtmp=X509_get_pubkey(xtmp))==NULL) goto end; if (dtmp->type == EVP_PKEY_EC) ec_params = EC_KEY_dup(dtmp->pkey.ec); EVP_PKEY_free(dtmp); X509_free(xtmp); if (ec_params == NULL) if (--argc < 1) goto bad; if (!genctx) { BIO_printf(bio_err,"Certificate does not contain EC parameters\n"); goto end; } BIO_puts(bio_err, "No keytype specified\n"); goto bad; } else else if (pkey_ctrl_string(genctx, *(++argv)) <= 0) { if (EC_KEY_set_group(ec_params, group) == 0) BIO_puts(bio_err, "parameter setting error\n"); ERR_print_errors(bio_err); goto end; EC_GROUP_free(group); } BIO_free(in); in=NULL; newkey = EC_GROUP_get_degree(EC_KEY_get0_group(ec_params)); } else #endif #ifndef OPENSSL_NO_DH if (strncmp("dh:",p,4) == 0) { pkey_type=TYPE_DH; p+=3; } else #endif { goto bad; } newreq=1; } else if (strcmp(*argv,"-batch") == 0) batch=1; Loading Loading @@ -731,9 +637,6 @@ bad: if (newreq && (pkey == NULL)) { #ifndef OPENSSL_NO_RSA BN_GENCB cb; #endif char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE"); if (randfile == NULL) ERR_clear_error(); Loading @@ -747,53 +650,35 @@ bad: newkey=DEFAULT_KEY_LENGTH; } if (newkey < MIN_KEY_LENGTH && (pkey_type == TYPE_RSA || pkey_type == TYPE_DSA)) if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) { BIO_printf(bio_err,"private key length is too short,\n"); BIO_printf(bio_err,"it needs to be at least %d bits, not %ld\n",MIN_KEY_LENGTH,newkey); goto end; } BIO_printf(bio_err,"Generating a %ld bit %s private key\n", newkey,(pkey_type == TYPE_RSA)?"RSA": (pkey_type == TYPE_DSA)?"DSA":"EC"); if ((pkey=EVP_PKEY_new()) == NULL) goto end; #ifndef OPENSSL_NO_RSA BN_GENCB_set(&cb, req_cb, bio_err); if (pkey_type == TYPE_RSA) { RSA *rsa = RSA_new(); BIGNUM *bn = BN_new(); if(!bn || !rsa || !BN_set_word(bn, 0x10001) || !RSA_generate_key_ex(rsa, newkey, bn, &cb) || !EVP_PKEY_assign_RSA(pkey, rsa)) if (!genctx) { if(bn) BN_free(bn); if(rsa) RSA_free(rsa); genctx = set_keygen_ctx(bio_err, NULL, &newkey, &keyalgstr, e); if (!genctx) goto end; } BN_free(bn); } else #endif #ifndef OPENSSL_NO_DSA if (pkey_type == TYPE_DSA) { if (!DSA_generate_key(dsa_params)) goto end; if (!EVP_PKEY_assign_DSA(pkey,dsa_params)) goto end; dsa_params=NULL; } #endif #ifndef OPENSSL_NO_ECDSA if (pkey_type == TYPE_EC) BIO_printf(bio_err,"Generating a %ld bit %s private key\n", newkey, keyalgstr); EVP_PKEY_CTX_set_cb(genctx, genpkey_cb); EVP_PKEY_CTX_set_app_data(genctx, bio_err); if (EVP_PKEY_keygen(genctx, &pkey) <= 0) { if (!EC_KEY_generate_key(ec_params)) goto end; if (!EVP_PKEY_assign_EC_KEY(pkey, ec_params)) BIO_puts(bio_err, "Error Generating Key\n"); goto end; ec_params = NULL; } #endif EVP_PKEY_CTX_free(genctx); genctx = NULL; app_RAND_write_file(randfile, bio_err); Loading Loading @@ -959,8 +844,11 @@ loop: } if (!(i=X509_sign(x509ss,pkey,digest))) { ERR_print_errors(bio_err); goto end; } } else { X509V3_CTX ext_ctx; Loading @@ -980,9 +868,12 @@ loop: goto end; } if (!(i=X509_REQ_sign(req,pkey,digest))) { ERR_print_errors(bio_err); goto end; } } } if (subj && x509) { Loading Loading @@ -1117,7 +1008,7 @@ loop: } fprintf(stdout,"Modulus="); #ifndef OPENSSL_NO_RSA if (tpubkey->type == EVP_PKEY_RSA) if (EVP_PKEY_base_id(tpubkey)) BN_print(out,tpubkey->pkey.rsa->n); else #endif Loading Loading @@ -1173,6 +1064,8 @@ end: BIO_free(in); BIO_free_all(out); EVP_PKEY_free(pkey); if (genctx) EVP_PKEY_CTX_free(genctx); X509_REQ_free(req); X509_free(x509ss); ASN1_INTEGER_free(serial); Loading Loading @@ -1631,24 +1524,6 @@ err: return(0); } #ifndef OPENSSL_NO_RSA static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb) { char c='*'; if (p == 0) c='.'; if (p == 1) c='+'; if (p == 2) c='*'; if (p == 3) c='\n'; BIO_write(cb->arg,&c,1); (void)BIO_flush(cb->arg); #ifdef LINT p=n; #endif return 1; } #endif static int req_check_len(int len, int n_min, int n_max) { if ((n_min > 0) && (len < n_min)) Loading @@ -1675,3 +1550,169 @@ static int check_end(const char *str, const char *end) tmp = str + slen - elen; return strcmp(tmp, end); } static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, long *pkeylen, const char **palgnam, ENGINE *e) { EVP_PKEY_CTX *gctx = NULL; EVP_PKEY *param = NULL; long keylen = -1; int pkey_type = -1; BIO *pbio = NULL; const char *paramfile = NULL; if (gstr == NULL) { pkey_type = EVP_PKEY_RSA; keylen = *pkeylen; } else if (gstr[0] >= '0' && gstr[0] <= '9') { pkey_type = EVP_PKEY_RSA; keylen = atol(gstr); *pkeylen = keylen; } else if (!strncmp(gstr, "param:", 6)) paramfile = gstr + 6; else { const char *p = strchr(gstr, ':'); int len; const EVP_PKEY_ASN1_METHOD *ameth; if (p) len = p - gstr; else len = strlen(gstr); ameth = EVP_PKEY_asn1_find_str(gstr, len); if (!ameth) { BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr); return NULL; } EVP_PKEY_asn1_get0_info(NULL, &pkey_type, NULL, NULL, NULL, ameth); if (pkey_type == EVP_PKEY_RSA) { if (p) { keylen = atol(p + 1); *pkeylen = keylen; } } else if (p) paramfile = p + 1; } if (paramfile) { pbio = BIO_new_file(paramfile, "r"); if (!pbio) { BIO_printf(err, "Can't open parameter file %s\n", paramfile); return NULL; } param = PEM_read_bio_Parameters(pbio, NULL); if (!param) { X509 *x; BIO_reset(pbio); x = PEM_read_bio_X509(pbio, NULL, NULL, NULL); if (x) { param = X509_get_pubkey(x); X509_free(x); } } BIO_free(pbio); if (!param) { BIO_printf(err, "Error reading parameter file %s\n", paramfile); return NULL; } if (pkey_type == -1) pkey_type = EVP_PKEY_id(param); else if (pkey_type != EVP_PKEY_base_id(param)) { BIO_printf(err, "Key Type does not match parameters\n"); EVP_PKEY_free(param); return NULL; } } if (palgnam) { const EVP_PKEY_ASN1_METHOD *ameth; ameth = EVP_PKEY_asn1_find(pkey_type); if (!ameth) { BIO_puts(err, "Internal error: can't find key algorithm\n"); return NULL; } EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, palgnam, ameth); } if (param) { gctx = EVP_PKEY_CTX_new(param, e); *pkeylen = EVP_PKEY_bits(param); EVP_PKEY_free(param); } else gctx = EVP_PKEY_CTX_new_id(pkey_type, e); if (!gctx) { BIO_puts(err, "Error allocating keygen context\n"); ERR_print_errors(err); return NULL; } if (EVP_PKEY_keygen_init(gctx) <= 0) { BIO_puts(err, "Error initializing keygen context\n"); ERR_print_errors(err); return NULL; } if ((pkey_type == EVP_PKEY_RSA) && (keylen != -1)) { if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) { BIO_puts(err, "Error setting RSA keysize\n"); ERR_print_errors(err); EVP_PKEY_CTX_free(gctx); return NULL; } } return gctx; } static int genpkey_cb(EVP_PKEY_CTX *ctx) { char c='*'; BIO *b = EVP_PKEY_CTX_get_app_data(ctx); int p; p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); if (p == 0) c='.'; if (p == 1) c='+'; if (p == 2) c='*'; if (p == 3) c='\n'; BIO_write(b,&c,1); (void)BIO_flush(b); #ifdef LINT p=n; #endif return 1; }