Main Page | Class List | Directories | File List | Class Members | File Members

req.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>

Go to the source code of this file.

Defines

#define SECTION   "req"
#define BITS   "default_bits"
#define KEYFILE   "default_keyfile"
#define PROMPT   "prompt"
#define DISTINGUISHED_NAME   "distinguished_name"
#define ATTRIBUTES   "attributes"
#define V3_EXTENSIONS   "x509_extensions"
#define REQ_EXTENSIONS   "req_extensions"
#define STRING_MASK   "string_mask"
#define UTF8_IN   "utf8"
#define DEFAULT_KEY_LENGTH   512
#define MIN_KEY_LENGTH   384
#define PROG   req_main
#define TYPE_RSA   1
#define TYPE_DSA   2
#define TYPE_DH   3
#define TYPE_EC   4

Functions

static int make_REQ (X509_REQ *req, EVP_PKEY *pkey, char *dn, int mutlirdn, int attribs, unsigned long chtype)
static int build_subject (X509_REQ *req, char *subj, unsigned long chtype, int multirdn)
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, unsigned long chtype)
static int auto_info (X509_REQ *req, STACK_OF(CONF_VALUE)*sk, STACK_OF(CONF_VALUE)*attr, int attribs, unsigned long chtype)
static int add_attribute_object (X509_REQ *req, char *text, const char *def, char *value, int nid, int n_min, 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)
static int MS_CALLBACK req_cb (int p, int n, BN_GENCB *cb)
static int req_check_len (int len, int n_min, int n_max)
static int check_end (const char *str, const char *end)
int MAIN (int, char **)

Variables

static char * default_config_file = NULL
static CONFreq_conf = NULL
static int batch = 0


Define Documentation

#define ATTRIBUTES   "attributes"
 

Definition at line 96 of file req.c.

Referenced by make_REQ().

#define BITS   "default_bits"
 

Definition at line 92 of file req.c.

#define DEFAULT_KEY_LENGTH   512
 

Definition at line 102 of file req.c.

#define DISTINGUISHED_NAME   "distinguished_name"
 

Definition at line 95 of file req.c.

Referenced by make_REQ().

#define KEYFILE   "default_keyfile"
 

Definition at line 93 of file req.c.

#define MIN_KEY_LENGTH   384
 

Definition at line 103 of file req.c.

#define PROG   req_main
 

Definition at line 106 of file req.c.

#define PROMPT   "prompt"
 

Definition at line 94 of file req.c.

Referenced by make_REQ().

#define REQ_EXTENSIONS   "req_extensions"
 

Definition at line 98 of file req.c.

#define SECTION   "req"
 

Definition at line 90 of file req.c.

Referenced by make_REQ().

#define STRING_MASK   "string_mask"
 

Definition at line 99 of file req.c.

#define TYPE_DH   3
 

Definition at line 157 of file req.c.

#define TYPE_DSA   2
 

Definition at line 156 of file req.c.

#define TYPE_EC   4
 

Definition at line 158 of file req.c.

#define TYPE_RSA   1
 

Definition at line 155 of file req.c.

#define UTF8_IN   "utf8"
 

Definition at line 100 of file req.c.

#define V3_EXTENSIONS   "x509_extensions"
 

Definition at line 97 of file req.c.


Function Documentation

static int add_attribute_object X509_REQ req,
char *  text,
const char *  def,
char *  value,
int  nid,
int  n_min,
int  n_max,
unsigned long  chtype
[static]
 

Definition at line 1579 of file req.c.

References bio_err, BIO_flush, BIO_printf(), BUF_strlcat(), BUF_strlcpy(), ebcdic2ascii, ERR_print_errors(), req_check_len(), void(), and X509_REQ_add1_attr_by_NID().

Referenced by prompt_info().

01582         {
01583         int i;
01584         static char buf[1024];
01585 
01586 start:
01587         if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def);
01588         (void)BIO_flush(bio_err);
01589         if (value != NULL)
01590                 {
01591                 BUF_strlcpy(buf,value,sizeof buf);
01592                 BUF_strlcat(buf,"\n",sizeof buf);
01593                 BIO_printf(bio_err,"%s\n",value);
01594                 }
01595         else
01596                 {
01597                 buf[0]='\0';
01598                 if (!batch)
01599                         {
01600                         fgets(buf,sizeof buf,stdin);
01601                         }
01602                 else
01603                         {
01604                         buf[0] = '\n';
01605                         buf[1] = '\0';
01606                         }
01607                 }
01608 
01609         if (buf[0] == '\0') return(0);
01610         else if (buf[0] == '\n')
01611                 {
01612                 if ((def == NULL) || (def[0] == '\0'))
01613                         return(1);
01614                 BUF_strlcpy(buf,def,sizeof buf);
01615                 BUF_strlcat(buf,"\n",sizeof buf);
01616                 }
01617         else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
01618 
01619         i=strlen(buf);
01620         if (buf[i-1] != '\n')
01621                 {
01622                 BIO_printf(bio_err,"weird input :-(\n");
01623                 return(0);
01624                 }
01625         buf[--i]='\0';
01626 #ifdef CHARSET_EBCDIC
01627         ebcdic2ascii(buf, buf, i);
01628 #endif
01629         if(!req_check_len(i, n_min, n_max)) goto start;
01630 
01631         if(!X509_REQ_add1_attr_by_NID(req, nid, chtype,
01632                                         (unsigned char *)buf, -1)) {
01633                 BIO_printf(bio_err, "Error adding attribute\n");
01634                 ERR_print_errors(bio_err);
01635                 goto err;
01636         }
01637 
01638         return(1);
01639 err:
01640         return(0);
01641         }

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
[static]
 

Definition at line 1523 of file req.c.

References bio_err, BIO_flush, BIO_printf(), BUF_strlcat(), BUF_strlcpy(), ebcdic2ascii, MS_STATIC, req_check_len(), ret, void(), and X509_NAME_add_entry_by_NID().

Referenced by prompt_info().

01525         {
01526         int i,ret=0;
01527         MS_STATIC char buf[1024];
01528 start:
01529         if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def);
01530         (void)BIO_flush(bio_err);
01531         if(value != NULL)
01532                 {
01533                 BUF_strlcpy(buf,value,sizeof buf);
01534                 BUF_strlcat(buf,"\n",sizeof buf);
01535                 BIO_printf(bio_err,"%s\n",value);
01536                 }
01537         else
01538                 {
01539                 buf[0]='\0';
01540                 if (!batch)
01541                         {
01542                         fgets(buf,sizeof buf,stdin);
01543                         }
01544                 else
01545                         {
01546                         buf[0] = '\n';
01547                         buf[1] = '\0';
01548                         }
01549                 }
01550 
01551         if (buf[0] == '\0') return(0);
01552         else if (buf[0] == '\n')
01553                 {
01554                 if ((def == NULL) || (def[0] == '\0'))
01555                         return(1);
01556                 BUF_strlcpy(buf,def,sizeof buf);
01557                 BUF_strlcat(buf,"\n",sizeof buf);
01558                 }
01559         else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
01560 
01561         i=strlen(buf);
01562         if (buf[i-1] != '\n')
01563                 {
01564                 BIO_printf(bio_err,"weird input :-(\n");
01565                 return(0);
01566                 }
01567         buf[--i]='\0';
01568 #ifdef CHARSET_EBCDIC
01569         ebcdic2ascii(buf, buf, i);
01570 #endif
01571         if(!req_check_len(i, n_min, n_max)) goto start;
01572         if (!X509_NAME_add_entry_by_NID(n,nid, chtype,
01573                                 (unsigned char *) buf, -1,-1,mval)) goto err;
01574         ret=1;
01575 err:
01576         return(ret);
01577         }

static int auto_info X509_REQ req,
STACK_OF(CONF_VALUE)*  sk,
STACK_OF(CONF_VALUE)*  attr,
int  attribs,
unsigned long  chtype
[static]
 

Definition at line 1459 of file req.c.

References bio_err, BIO_printf(), CONF_VALUE::name, os_toascii, sk_CONF_VALUE_num, sk_CONF_VALUE_value, type, CONF_VALUE::value, X509_NAME_add_entry_by_txt(), X509_NAME_entry_count(), X509_REQ_add1_attr_by_txt(), and X509_REQ_get_subject_name.

Referenced by make_REQ().

01461         {
01462         int i;
01463         char *p,*q;
01464         char *type;
01465         CONF_VALUE *v;
01466         X509_NAME *subj;
01467 
01468         subj = X509_REQ_get_subject_name(req);
01469 
01470         for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
01471                 {
01472                 int mval;
01473                 v=sk_CONF_VALUE_value(dn_sk,i);
01474                 p=q=NULL;
01475                 type=v->name;
01476                 /* Skip past any leading X. X: X, etc to allow for
01477                  * multiple instances 
01478                  */
01479                 for(p = v->name; *p ; p++) 
01480 #ifndef CHARSET_EBCDIC
01481                         if ((*p == ':') || (*p == ',') || (*p == '.')) {
01482 #else
01483                         if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.'])) {
01484 #endif
01485                                 p++;
01486                                 if(*p) type = p;
01487                                 break;
01488                         }
01489 #ifndef CHARSET_EBCDIC
01490                 if (*p == '+')
01491 #else
01492                 if (*p == os_toascii['+'])
01493 #endif
01494                         {
01495                         p++;
01496                         mval = -1;
01497                         }
01498                 else
01499                         mval = 0;
01500                 if (!X509_NAME_add_entry_by_txt(subj,type, chtype,
01501                                 (unsigned char *) v->value,-1,-1,mval)) return 0;
01502 
01503                 }
01504 
01505                 if (!X509_NAME_entry_count(subj))
01506                         {
01507                         BIO_printf(bio_err,"error, no objects specified in config file\n");
01508                         return 0;
01509                         }
01510                 if (attribs)
01511                         {
01512                         for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++)
01513                                 {
01514                                 v=sk_CONF_VALUE_value(attr_sk,i);
01515                                 if(!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
01516                                         (unsigned char *)v->value, -1)) return 0;
01517                                 }
01518                         }
01519         return 1;
01520         }

static int build_subject X509_REQ req,
char *  subj,
unsigned long  chtype,
int  multirdn
[static]
 

Definition at line 1269 of file req.c.

References parse_name(), and X509_REQ_set_subject_name().

Referenced by make_REQ().

01270         {
01271         X509_NAME *n;
01272 
01273         if (!(n = parse_name(subject, chtype, multirdn)))
01274                 return 0;
01275 
01276         if (!X509_REQ_set_subject_name(req, n))
01277                 {
01278                 X509_NAME_free(n);
01279                 return 0;
01280                 }
01281         X509_NAME_free(n);
01282         return 1;
01283 }

static int check_end const char *  str,
const char *  end
[static]
 

Definition at line 1677 of file req.c.

Referenced by prompt_info().

01678 {
01679         int elen, slen; 
01680         const char *tmp;
01681         elen = strlen(end);
01682         slen = strlen(str);
01683         if(elen > slen) return 1;
01684         tmp = str + slen - elen;
01685         return strcmp(tmp, end);
01686 }

int MAIN int  ,
char ** 
 

static int make_REQ X509_REQ req,
EVP_PKEY pkey,
char *  dn,
int  mutlirdn,
int  attribs,
unsigned long  chtype
[static]
 

Definition at line 1201 of file req.c.

References ATTRIBUTES, auto_info(), bio_err, BIO_printf(), build_subject(), DISTINGUISHED_NAME, ERR_clear_error(), NCONF_get_string(), PROMPT, prompt_info(), ret, SECTION, STACK_OF, X509_REQ_set_pubkey(), and X509_REQ_set_version().

01203         {
01204         int ret=0,i;
01205         char no_prompt = 0;
01206         STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL;
01207         char *tmp, *dn_sect,*attr_sect;
01208 
01209         tmp=NCONF_get_string(req_conf,SECTION,PROMPT);
01210         if (tmp == NULL)
01211                 ERR_clear_error();
01212         if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1;
01213 
01214         dn_sect=NCONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME);
01215         if (dn_sect == NULL)
01216                 {
01217                 BIO_printf(bio_err,"unable to find '%s' in config\n",
01218                         DISTINGUISHED_NAME);
01219                 goto err;
01220                 }
01221         dn_sk=NCONF_get_section(req_conf,dn_sect);
01222         if (dn_sk == NULL)
01223                 {
01224                 BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect);
01225                 goto err;
01226                 }
01227 
01228         attr_sect=NCONF_get_string(req_conf,SECTION,ATTRIBUTES);
01229         if (attr_sect == NULL)
01230                 {
01231                 ERR_clear_error();              
01232                 attr_sk=NULL;
01233                 }
01234         else
01235                 {
01236                 attr_sk=NCONF_get_section(req_conf,attr_sect);
01237                 if (attr_sk == NULL)
01238                         {
01239                         BIO_printf(bio_err,"unable to get '%s' section\n",attr_sect);
01240                         goto err;
01241                         }
01242                 }
01243 
01244         /* setup version number */
01245         if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */
01246 
01247         if (no_prompt) 
01248                 i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
01249         else 
01250                 {
01251                 if (subj)
01252                         i = build_subject(req, subj, chtype, multirdn);
01253                 else
01254                         i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype);
01255                 }
01256         if(!i) goto err;
01257 
01258         if (!X509_REQ_set_pubkey(req,pkey)) goto err;
01259 
01260         ret=1;
01261 err:
01262         return(ret);
01263         }

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,
unsigned long  chtype
[static]
 

Definition at line 1286 of file req.c.

References add_attribute_object(), add_DN_object(), bio_err, BIO_printf(), BIO_snprintf(), check_end(), ERR_clear_error(), CONF_VALUE::name, NCONF_get_number, NCONF_get_string(), nid, NID_undef, OBJ_txt2nid(), sk_CONF_VALUE_num, sk_CONF_VALUE_value, type, CONF_VALUE::value, X509_NAME_entry_count(), and X509_REQ_get_subject_name.

Referenced by make_REQ(), and password_callback().

01290         {
01291         int i;
01292         char *p,*q;
01293         char buf[100];
01294         int nid, mval;
01295         long n_min,n_max;
01296         char *type, *value;
01297         const char *def;
01298         CONF_VALUE *v;
01299         X509_NAME *subj;
01300         subj = X509_REQ_get_subject_name(req);
01301 
01302         if(!batch)
01303                 {
01304                 BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n");
01305                 BIO_printf(bio_err,"into your certificate request.\n");
01306                 BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n");
01307                 BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n");
01308                 BIO_printf(bio_err,"For some fields there will be a default value,\n");
01309                 BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n");
01310                 BIO_printf(bio_err,"-----\n");
01311                 }
01312 
01313 
01314         if (sk_CONF_VALUE_num(dn_sk))
01315                 {
01316                 i= -1;
01317 start:          for (;;)
01318                         {
01319                         i++;
01320                         if (sk_CONF_VALUE_num(dn_sk) <= i) break;
01321 
01322                         v=sk_CONF_VALUE_value(dn_sk,i);
01323                         p=q=NULL;
01324                         type=v->name;
01325                         if(!check_end(type,"_min") || !check_end(type,"_max") ||
01326                                 !check_end(type,"_default") ||
01327                                          !check_end(type,"_value")) continue;
01328                         /* Skip past any leading X. X: X, etc to allow for
01329                          * multiple instances 
01330                          */
01331                         for(p = v->name; *p ; p++) 
01332                                 if ((*p == ':') || (*p == ',') ||
01333                                                          (*p == '.')) {
01334                                         p++;
01335                                         if(*p) type = p;
01336                                         break;
01337                                 }
01338                         if (*type == '+')
01339                                 {
01340                                 mval = -1;
01341                                 type++;
01342                                 }
01343                         else
01344                                 mval = 0;
01345                         /* If OBJ not recognised ignore it */
01346                         if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start;
01347                         if (BIO_snprintf(buf,sizeof buf,"%s_default",v->name)
01348                                 >= (int)sizeof(buf))
01349                            {
01350                            BIO_printf(bio_err,"Name '%s' too long\n",v->name);
01351                            return 0;
01352                            }
01353 
01354                         if ((def=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
01355                                 {
01356                                 ERR_clear_error();
01357                                 def="";
01358                                 }
01359                                 
01360                         BIO_snprintf(buf,sizeof buf,"%s_value",v->name);
01361                         if ((value=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
01362                                 {
01363                                 ERR_clear_error();
01364                                 value=NULL;
01365                                 }
01366 
01367                         BIO_snprintf(buf,sizeof buf,"%s_min",v->name);
01368                         if (!NCONF_get_number(req_conf,dn_sect,buf, &n_min))
01369                                 {
01370                                 ERR_clear_error();
01371                                 n_min = -1;
01372                                 }
01373 
01374                         BIO_snprintf(buf,sizeof buf,"%s_max",v->name);
01375                         if (!NCONF_get_number(req_conf,dn_sect,buf, &n_max))
01376                                 {
01377                                 ERR_clear_error();
01378                                 n_max = -1;
01379                                 }
01380 
01381                         if (!add_DN_object(subj,v->value,def,value,nid,
01382                                 n_min,n_max, chtype, mval))
01383                                 return 0;
01384                         }
01385                 if (X509_NAME_entry_count(subj) == 0)
01386                         {
01387                         BIO_printf(bio_err,"error, no objects specified in config file\n");
01388                         return 0;
01389                         }
01390 
01391                 if (attribs)
01392                         {
01393                         if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) && (!batch))
01394                                 {
01395                                 BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n");
01396                                 BIO_printf(bio_err,"to be sent with your certificate request\n");
01397                                 }
01398 
01399                         i= -1;
01400 start2:                 for (;;)
01401                                 {
01402                                 i++;
01403                                 if ((attr_sk == NULL) ||
01404                                             (sk_CONF_VALUE_num(attr_sk) <= i))
01405                                         break;
01406 
01407                                 v=sk_CONF_VALUE_value(attr_sk,i);
01408                                 type=v->name;
01409                                 if ((nid=OBJ_txt2nid(type)) == NID_undef)
01410                                         goto start2;
01411 
01412                                 if (BIO_snprintf(buf,sizeof buf,"%s_default",type)
01413                                         >= (int)sizeof(buf))
01414                                    {
01415                                    BIO_printf(bio_err,"Name '%s' too long\n",v->name);
01416                                    return 0;
01417                                    }
01418 
01419                                 if ((def=NCONF_get_string(req_conf,attr_sect,buf))
01420                                         == NULL)
01421                                         {
01422                                         ERR_clear_error();
01423                                         def="";
01424                                         }
01425                                 
01426                                 
01427                                 BIO_snprintf(buf,sizeof buf,"%s_value",type);
01428                                 if ((value=NCONF_get_string(req_conf,attr_sect,buf))
01429                                         == NULL)
01430                                         {
01431                                         ERR_clear_error();
01432                                         value=NULL;
01433                                         }
01434 
01435                                 BIO_snprintf(buf,sizeof buf,"%s_min",type);
01436                                 if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min))
01437                                         n_min = -1;
01438 
01439                                 BIO_snprintf(buf,sizeof buf,"%s_max",type);
01440                                 if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max))
01441                                         n_max = -1;
01442 
01443                                 if (!add_attribute_object(req,
01444                                         v->value,def,value,nid,n_min,n_max, chtype))
01445                                         return 0;
01446                                 }
01447                         }
01448                 }
01449         else
01450                 {
01451                 BIO_printf(bio_err,"No template, please set one up.\n");
01452                 return 0;
01453                 }
01454 
01455         return 1;
01456 
01457         }

static int MS_CALLBACK req_cb int  p,
int  n,
BN_GENCB cb
[static]
 

Definition at line 1644 of file req.c.

References bn_gencb_st::arg, BIO_flush, BIO_write(), c, and void().

01645         {
01646         char c='*';
01647 
01648         if (p == 0) c='.';
01649         if (p == 1) c='+';
01650         if (p == 2) c='*';
01651         if (p == 3) c='\n';
01652         BIO_write(cb->arg,&c,1);
01653         (void)BIO_flush(cb->arg);
01654 #ifdef LINT
01655         p=n;
01656 #endif
01657         return 1;
01658         }

static int req_check_len int  len,
int  n_min,
int  n_max
[static]
 

Definition at line 1661 of file req.c.

References bio_err, and BIO_printf().

Referenced by add_attribute_object(), and add_DN_object().

01662         {
01663         if ((n_min > 0) && (len < n_min))
01664                 {
01665                 BIO_printf(bio_err,"string is too short, it needs to be at least %d bytes long\n",n_min);
01666                 return(0);
01667                 }
01668         if ((n_max >= 0) && (len > n_max))
01669                 {
01670                 BIO_printf(bio_err,"string is too long, it needs to be less than  %d bytes long\n",n_max);
01671                 return(0);
01672                 }
01673         return(1);
01674         }


Variable Documentation

int batch = 0 [static]
 

Definition at line 153 of file req.c.

char* default_config_file = NULL [static]
 

Definition at line 150 of file req.c.

CONF* req_conf = NULL [static]
 

Definition at line 152 of file req.c.


© sourcejam.com 2005-2008