--- openssl-0.9.5a/apps/ca.c-stock Mon Mar 13 18:54:04 2000 +++ openssl-0.9.5a/apps/ca.c Wed Jan 16 15:55:05 2002 @@ -63,6 +63,7 @@ #include #include #include +#include #include "apps.h" #include #include @@ -98,7 +99,7 @@ #define PROG ca_main #define BASE_SECTION "ca" -#define CONFIG_FILE "openssl.cnf" +#define CONFIG_FILE "etc/openssl.cnf" #define ENV_DEFAULT_CA "default_ca" @@ -155,6 +156,7 @@ " -keyfile arg - PEM private key file\n", " -key arg - key to decode the private key if it is encrypted\n", " -cert file - The CA certificate\n", +" -rawkey file - A raw hex or base64 encoded public key to sign.\n", " -in file - The input PEM encoded certificate request(s)\n", " -out file - Where to put the output file(s)\n", " -outdir dir - Where to put output certificates\n", @@ -176,6 +178,8 @@ extern int EF_ALIGNMENT; #endif +int make_REQ(X509_REQ *req,EVP_PKEY *pkey,int attribs); + static int add_oid_section(LHASH *conf); static void lookup_fail(char *name,char *tag); static unsigned long index_serial_hash(char **a); @@ -199,6 +203,11 @@ TXT_DB *db, BIGNUM *serial,char *startdate, char *enddate, int days, char *ext_sect,LHASH *conf, int verbose); +static int certify_rawkey(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, + const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, + BIGNUM *serial, char *startdate, char *enddate, int days, + int batch, char *ext_sect, LHASH *lconf, int verbose); + static int fix_data(int nid, int *type); static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext); static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, @@ -234,6 +243,7 @@ char *policy=NULL; char *keyfile=NULL; char *certfile=NULL; + char *raw_key_file=NULL; char *infile=NULL; char *spkac_file=NULL; char *ss_cert_file=NULL; @@ -344,6 +354,12 @@ if (--argc < 1) goto bad; certfile= *(++argv); } + else if (strcmp(*argv,"-rawkey") == 0) + { + if (--argc < 1) goto bad; + raw_key_file = *(++argv); + req=1; + } else if (strcmp(*argv,"-in") == 0) { if (--argc < 1) goto bad; @@ -846,6 +862,25 @@ } } } + if (raw_key_file != NULL) + { + total++; + j=certify_rawkey(&x,raw_key_file,pkey,x509,dgst,attribs, + db,serial,startdate,enddate,days,batch, + extensions,conf,verbose); + if (j < 0) goto err; + if (j > 0) + { + total_done++; + BIO_printf(bio_err,"\n"); + if (!BN_add_word(serial,1)) goto err; + if (!sk_push(cert_sk,(char *)x)) + { + BIO_printf(bio_err,"Malloc failure\n"); + goto err; + } + } + } if (ss_cert_file != NULL) { total++; @@ -1408,6 +1443,169 @@ if (in != NULL) BIO_free(in); return(ok); } + +static int hexdigit(char hex) +{ + if(hex >= '0' && hex <= '9') { + return (hex - '0'); + } else if(hex >= 'A' && hex <= 'F') { + return (hex - 'A' + 10); + } else if(hex >= 'a' && hex <= 'f') { + return (hex - 'a' + 10); + } else { + printf("invalid hex digit %c in espsecret\n", hex); + return -1; + } +} + +static int certify_rawkey(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, + const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, + BIGNUM *serial, char *startdate, char *enddate, int days, + int batch, char *ext_sect, LHASH *lconf, int verbose) + { + X509_REQ *req=NULL; + BIO *in=NULL, *b64; + int ok= -1; + EVP_PKEY *rawkey; + char *rawpubkey; + int rawpubkeysize; + int nibble; + int gotnibble; + int keyindex; + int explen; + unsigned char c; + int prefixstate; + + extern LHASH *req_conf; + + req_conf = NULL; + in=BIO_new(BIO_s_file()); + + if (BIO_read_filename(in,infile) <= 0) + { + perror(infile); + goto err; + } + + /* take a guess on initial key size */ + rawpubkeysize=2048 + 256; + rawpubkey=malloc(rawpubkeysize); + keyindex = 0; + nibble = 0; + gotnibble= 0; + prefixstate= 0; + + while(BIO_read(in, &c, 1) > 0) { + + switch(prefixstate) { + case 0: + if(c=='0') { + prefixstate=1; + } else if(!isspace(c)) { + fprintf(stderr, + "unknown character '%c' (%02x) in key encoding, assuming base64.\n", + isprint(c) ? c : '.', c); + } + continue; + + case 1: + /* if we see an "x" as in "0x", then we skip it and set the base */ + if(c=='x') { + gotnibble=0; + prefixstate=2; + } + else if(c=='s') { + prefixstate=3; + if(!(b64 = BIO_new(BIO_f_base64()))) { + fprintf(stderr, "failed to allocate BIO_f_base64 for reading public key.\n"); + exit(1); + } + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + in = BIO_push(b64, in); + } else { + goto badchar; + } + continue; + + case 2: + if(isspace(c) || c=='_') { + continue; + } + + if(hexdigit(c) != -1) { + if(gotnibble) { + if(keyindex == rawpubkeysize) { + /* expand rawpubkey */ + rawpubkeysize = rawpubkeysize*2; + rawpubkey = realloc(rawpubkey, rawpubkeysize); + if(rawpubkey == NULL) { + fprintf(stderr, + "Raw out of memory allocating space for %d public key\n", + rawpubkeysize); + exit(1); + } + } + rawpubkey[keyindex++]=(nibble<<4) + hexdigit(c); + gotnibble=0; + } else { + gotnibble=1; + nibble=hexdigit(c); + } + } + continue; + + case 3: + if(keyindex == rawpubkeysize) { + /* expand rawpubkey */ + rawpubkeysize = rawpubkeysize*2; + rawpubkey = realloc(rawpubkey, rawpubkeysize); + if(rawpubkey == NULL) { + fprintf(stderr, + "Raw out of memory allocating space for %d public key\n", + rawpubkeysize); + exit(1); + } + } + rawpubkey[keyindex++]=c; + continue; + } + } + + rawkey = malloc(sizeof(EVP_PKEY)); + rawkey->type = EVP_PKEY_RSA; + + /* first byte of RSA key is length of exponent bytes */ + explen = rawpubkey[0]; + + rawkey->pkey.rsa->e = BN_bin2bn(rawpubkey+1, explen, NULL); + rawkey->pkey.rsa->n = BN_bin2bn(rawpubkey+explen+1, keyindex-explen-1, NULL); + + req = X509_REQ_new(); + if(req == NULL) { + fprintf(stderr, "failed to create new REQ structure\n"); + exit(1); + } + + /* from x509_req.c */ + + /* version == 0 */ + req->req_info->version->length=1; + req->req_info->version->data=(unsigned char *)Malloc(1); + if (req->req_info->version->data == NULL) goto err; + req->req_info->version->data[0]=0; + + req_conf=lconf; + + make_REQ(req, rawkey, 0); + + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days, + batch,verbose,req,ext_sect,lconf); + +err: + if (req != NULL) X509_REQ_free(req); + if (in != NULL) BIO_free(in); + return(ok); +} static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, --- openssl-0.9.5a/apps/req.c-stock Mon Mar 13 18:54:07 2000 +++ openssl-0.9.5a/apps/req.c Wed Jan 16 15:32:47 2002 @@ -109,7 +109,7 @@ * require. This format is wrong */ -static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,int attribs); +int make_REQ(X509_REQ *req,EVP_PKEY *pkey,int attribs); static int prompt_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs); @@ -130,7 +130,7 @@ static char *default_config_file=NULL; static LHASH *config=NULL; #endif -static LHASH *req_conf=NULL; +LHASH *req_conf=NULL; #define TYPE_RSA 1 #define TYPE_DSA 2 @@ -887,7 +887,7 @@ EXIT(ex); } -static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs) +int make_REQ(X509_REQ *req, EVP_PKEY *pkey, int attribs) { int ret=0,i; char no_prompt = 0;