Example #1
0
/*  openssl.object_create(string oid, string name[, string alias] | tables args ) -> boolean{{{1
*/
int openssl_object_create(lua_State* L) 
{
	int ret = 0;

	const char* oid;
	const char* name;
	const char* alias;

	if (!lua_istable(L,1))
	{
		oid = luaL_checkstring(L,1);
		name = luaL_checkstring(L,2);
		alias = luaL_optstring(L,3,name);

		ret = OBJ_create(oid, name, alias) != NID_undef;
		lua_pushboolean(L,ret);
		if(!ret)
		{
			lua_pushfstring(L,"create object(%s) with name(%s) failed",oid,name);
			ret = 2;
		}else
			ret = 1;
		return ret;
	}else
	{
		size_t i;
		for (i = 1; i <= lua_objlen(L,1); i++) {
			lua_rawgeti(L,-1, i);
			if(lua_istable(L,-1))
			{
				lua_getfield(L,-1,"oid");
				oid = luaL_checkstring(L,-1);
				lua_pop(L,1);
				lua_getfield(L,-2,"name");
				name = luaL_checkstring(L,-1);
				lua_pop(L,1);
				lua_getfield(L,-3,"alias");
				alias = luaL_optstring(L,-1,name);
				lua_pop(L,1);
				if(OBJ_create(oid, name, alias) == NID_undef)
				{
					luaL_error(L,"create object(%s) with name(%s) failed at %d",oid,name,i);
				}
			}
			lua_pop(L,1);
		}
		lua_pushboolean(L,1);
		return 1;
	}
	return 0;
}
int get_signed_string(PKCS7_SIGNER_INFO *si, char *buf, int len)
	{
	ASN1_TYPE *so;
	ASN1_OCTET_STRING *os;
	int i;

	if (signed_string_nid == -1)
		signed_string_nid=
			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
	/* To retrieve */
	so=PKCS7_get_signed_attribute(si,signed_string_nid);
	if (so != NULL)
		{
		if (so->type == V_ASN1_OCTET_STRING)
			{
			os=so->value.octet_string;
			i=os->length;
			if ((i+1) > len)
				i=len-1;
			TINYCLR_SSL_MEMCPY(buf,os->data,i);
			return(i);
			}
		}
	return(0);
	}
Example #3
0
/**
 * Constructor.
 * @param p the secure server port.
 * @param b the backlog, that is the maximum number of outstanding connection requests.
 */
GSISocketClient::GSISocketClient(const std::string &h, int p) :
  host(h), port(p),
  opened(false), own_subject(""),
  upkey(NULL), ucert(NULL), cacertdir(NULL),
  ssl(NULL), ctx(NULL),
  conn(NULL), error(""), timeout(-1)
{
  OBJ_create("0.9.2342.19200300.100.1.1","USERID","userId");
}
Example #4
0
/*
 * initialize the openssl library and any library related data structures
 * used in all SCEP transactions
 * XXX improve error checking
 */
int	scepinit(void) {
	int		i;
	unsigned char	randpool[1024];
	struct stat	sb;

	/* initialize the syslog					*/
	openlog("scep", LOG_PID|LOG_NDELAY, LOG_FACILITY);

	/* log the version of scepd starting				*/
	syslog(LOG_DEBUG, "version %s starting", openscep_version.v_long);

	/* initialize error message strings				*/
	ERR_load_crypto_strings();
	if (debug)
		fprintf(stderr, "%s:%d: crypto strings loaded\n", __FILE__,
			__LINE__);

	/* add the encryption algorithms available			*/
	OpenSSL_add_all_algorithms();
	if (debug)
		fprintf(stderr, "%s:%d: algorithms added\n", __FILE__,
			__LINE__);

	/* provide a entropy source					*/
	RAND_seed(randpool, sizeof(randpool));
	if (debug)
		fprintf(stderr, "%s:%d: random source seeded\n", __FILE__,
			__LINE__);

	/* activate the standard error BIO, which we use for error	*/
	/* messages							*/
	if ((bio_err = BIO_new(BIO_s_file())) != NULL)
		BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
	if (debug)
		BIO_printf(bio_err, "%s:%d: stderr BIO initialized\n",
			__FILE__, __LINE__);

	/* define the new object definitions needed for SCEP		*/
	for (i = 0; i < NEW_NIDS; i++) {
		scep_oid_def[i].nid = OBJ_create(scep_oid_def[i].oid,
			scep_oid_def[i].name1, scep_oid_def[i].name2);
		if (debug)
			BIO_printf(bio_err, "%s:%d: added oid %s for name %s\n",
				__FILE__, __LINE__, scep_oid_def[i].oid,
				scep_oid_def[i].name1);
	}

	/* find out whether the /var/tmp/openscep directory is there	*/
	if (stat(TMPPATH, &sb) == 0) {
		if (S_ISDIR(sb.st_mode))
			if (access(TMPPATH, W_OK) == 0)
				tmppath = TMPPATH;
	}

	/* no problem encountered					*/
	return 0;
}
Example #5
0
File: ssl.c Project: N0NB/aprx
static int load_tqsl_custom_objects(void)
{
	int i;
	
	for (i = 0; i < (sizeof tqsl_NIDs / sizeof tqsl_NIDs[0]); ++i)
		if (OBJ_create(tqsl_NIDs[i][0], tqsl_NIDs[i][1], NULL) == 0)
			return -1;
	
	return 0;
}
Example #6
0
/*
 * This function adds the TBB extensions to the internal extension list
 * maintained by OpenSSL so they can be used later.
 *
 * It also initializes the methods to print the contents of the extension. If an
 * alias is specified in the TBB extension, we reuse the methods of the alias.
 * Otherwise, only methods for V_ASN1_INTEGER and V_ASN1_OCTET_STRING are
 * provided. Any other type will be printed as a raw ascii string.
 *
 * Return: 0 = success, Otherwise: error
 */
int ext_init(void)
{
	cmd_opt_t cmd_opt;
	ext_t *ext;
	X509V3_EXT_METHOD *m;
	int nid, ret;
	unsigned int i;

	for (i = 0; i < num_extensions; i++) {
		ext = &extensions[i];
		/* Register command line option */
		if (ext->opt) {
			cmd_opt.long_opt.name = ext->opt;
			cmd_opt.long_opt.has_arg = required_argument;
			cmd_opt.long_opt.flag = NULL;
			cmd_opt.long_opt.val = CMD_OPT_EXT;
			cmd_opt.help_msg = ext->help_msg;
			cmd_opt_add(&cmd_opt);
		}
		/* Register the extension OID in OpenSSL */
		if (ext->oid == NULL) {
			continue;
		}
		nid = OBJ_create(ext->oid, ext->sn, ext->ln);
		if (ext->alias) {
			X509V3_EXT_add_alias(nid, ext->alias);
		} else {
			m = &ext->method;
			memset(m, 0x0, sizeof(X509V3_EXT_METHOD));
			switch (ext->asn1_type) {
			case V_ASN1_INTEGER:
				m->it = ASN1_ITEM_ref(ASN1_INTEGER);
				m->i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER;
				m->s2i = (X509V3_EXT_S2I)s2i_ASN1_INTEGER;
				break;
			case V_ASN1_OCTET_STRING:
				m->it = ASN1_ITEM_ref(ASN1_OCTET_STRING);
				m->i2s = (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING;
				m->s2i = (X509V3_EXT_S2I)s2i_ASN1_OCTET_STRING;
				break;
			default:
				continue;
			}
			m->ext_nid = nid;
			ret = X509V3_EXT_add(m);
			if (!ret) {
				ERR_print_errors_fp(stdout);
				return 1;
			}
		}
	}
	return 0;
}
Example #7
0
/**
 * Constructor.
 * @param p the secure server port.
 * @param b the backlog, that is the maximum number of outstanding connection requests.
 */
GSISocketServer::GSISocketServer(int p, void *l, int b, bool m) :
  own_subject(""), own_ca(""), peer_subject(""), 
  peer_ca(""), peer_serial(""), own_key(NULL), own_cert(NULL), 
  peer_cert(NULL), own_stack(NULL), peer_stack(NULL), 
  ssl(NULL), ctx(NULL), conn(NULL), pvd(NULL), cacertdir(NULL),
  upkey(NULL), ucert(NULL), error(""),
  port(p), opened(false), sck(-1), backlog(b), newsock(-1), timeout(30),
  newopened(false), mustclose(m), logh(l)
{
  if (OBJ_txt2nid("UID") == NID_undef)
    OBJ_create("0.9.2342.19200300.100.1.1","USERID","userId");
}
void add_signed_string(PKCS7_SIGNER_INFO *si, char *str)
	{
	ASN1_OCTET_STRING *os;

	/* To a an object of OID 1.2.3.4.5, which is an octet string */
	if (signed_string_nid == -1)
		signed_string_nid=
			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
	os=ASN1_OCTET_STRING_new();
	ASN1_OCTET_STRING_set(os,(unsigned char*)str,TINYCLR_SSL_STRLEN(str));
	/* When we add, we do not free */
	PKCS7_add_signed_attribute(si,signed_string_nid,
		V_ASN1_OCTET_STRING,(char *)os);
	}
Example #9
0
static int do_create(char const *value, char const *name)
{
    int nid;
    ASN1_OBJECT *oid;
    char const *ln, *ostr, *p;
    char *lntmp;
    p = strrchr(value, ',');
    if (!p)
    {
        ln = name;
        ostr = value;
    }
    else
    {
        ln = NULL;
        ostr = p + 1;
        if (!*ostr)
            return 0;
        while(isspace((unsigned char)*ostr)) ostr++;
    }

    nid = OBJ_create(ostr, name, ln);

    if (nid == NID_undef)
        return 0;

    if (p)
    {
        ln = value;
        while(isspace((unsigned char)*ln)) ln++;
        p--;
        while(isspace((unsigned char)*p))
        {
            if (p == ln)
                return 0;
            p--;
        }
        p++;
        lntmp = OPENSSL_malloc((p - ln) + 1);
        if (lntmp == NULL)
            return 0;
        memcpy(lntmp, ln, p - ln);
        lntmp[p - ln] = 0;
        oid = OBJ_nid2obj(nid);
        oid->ln = lntmp;
    }

    return 1;
}
Example #10
0
/* For this case, I will malloc the return strings */
int
get_signed_seq2string(PKCS7_SIGNER_INFO *si, char **str1, char **str2)
{
	ASN1_TYPE *so;

	if (signed_seq2string_nid == -1)
		signed_seq2string_nid =
		    OBJ_create("1.9.9999","OID_example","Our example OID");
	/* To retrieve */
	so = PKCS7_get_signed_attribute(si, signed_seq2string_nid);
	if (so && (so->type == V_ASN1_SEQUENCE)) {
		ASN1_const_CTX c;
		ASN1_STRING *s;
		long length;
		ASN1_OCTET_STRING *os1, *os2;

		s = so->value.sequence;
		c.p = ASN1_STRING_data(s);
		c.max = c.p + ASN1_STRING_length(s);
		if (!asn1_GetSequence(&c, &length))
			goto err;
		/* Length is the length of the seqence */

		c.q = c.p;
		if ((os1 = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL)
			goto err;
		c.slen -= (c.p - c.q);

		c.q = c.p;
		if ((os2 = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL)
			goto err;
		c.slen -= (c.p - c.q);

		if (!asn1_const_Finish(&c))
			goto err;
		*str1 = malloc(os1->length + 1);
		*str2 = malloc(os2->length + 1);
		memcpy(*str1, os1->data, os1->length);
		memcpy(*str2, os2->data, os2->length);
		(*str1)[os1->length]='\0';
		(*str2)[os2->length]='\0';
		ASN1_OCTET_STRING_free(os1);
		ASN1_OCTET_STRING_free(os2);
		return (1);
	}
err:
	return (0);
}
Example #11
0
int OBJ_create_objects(BIO *in)
  {
  MS_STATIC char buf[512];
  int i,num=0;
  char *o,*s,*l=NULL;

  for (;;)
    {
    s=o=NULL;
    i=BIO_gets(in,buf,512);
    if (i <= 0) return(num);
    buf[i-1]='\0';
    if (!isalnum((unsigned char)buf[0])) return(num);
    o=s=buf;
    while (isdigit((unsigned char)*s) || (*s == '.'))
      s++;
    if (*s != '\0')
      {
      *(s++)='\0';
      while (isspace((unsigned char)*s))
        s++;
      if (*s == '\0')
        s=NULL;
      else
        {
        l=s;
        while ((*l != '\0') && !isspace((unsigned char)*l))
          l++;
        if (*l != '\0')
          {
          *(l++)='\0';
          while (isspace((unsigned char)*l))
            l++;
          if (*l == '\0') l=NULL;
          }
        else
          l=NULL;
        }
      }
    else
      s=NULL;
    if ((o == NULL) || (*o == '\0')) return(num);
    if (!OBJ_create(o,s,l)) return(num);
    num++;
    }
  /* return(num); */
  }
Example #12
0
/* ########################################### */
int
add_signed_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
{
	/* To add an object of OID 1.9.999, which is a sequence containing
	 * 2 octet strings */
	unsigned char *p;
	ASN1_OCTET_STRING *os1, *os2;
	ASN1_STRING *seq;
	unsigned char *data;
	int i, total;

	if (signed_seq2string_nid == -1)
		signed_seq2string_nid =
		    OBJ_create("1.9.9999","OID_example","Our example OID");

	os1 = ASN1_OCTET_STRING_new();
	os2 = ASN1_OCTET_STRING_new();
	ASN1_OCTET_STRING_set(os1, (unsigned char*)str1, strlen(str1));
	ASN1_OCTET_STRING_set(os2, (unsigned char*)str1, strlen(str1));
	i = i2d_ASN1_OCTET_STRING(os1, NULL);
	i += i2d_ASN1_OCTET_STRING(os2, NULL);
	total = ASN1_object_size(1, i, V_ASN1_SEQUENCE);

	data = malloc(total);
	p = data;
	ASN1_put_object(&p, 1,i, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
	i2d_ASN1_OCTET_STRING(os1, &p);
	i2d_ASN1_OCTET_STRING(os2, &p);

	seq = ASN1_STRING_new();
	ASN1_STRING_set(seq, data, total);
	free(data);
	ASN1_OCTET_STRING_free(os1);
	ASN1_OCTET_STRING_free(os2);

	PKCS7_add_signed_attribute(si, signed_seq2string_nid,
	    V_ASN1_SEQUENCE, (char *)seq);
	return (1);
}
Example #13
0
int GT_init(void)
{
	int res = GT_UNKNOWN_ERROR;

	if (init_count++ > 0) {
		/* Nothing to do: already initialized. */
		return GT_OK;
	}

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Create NID for the id-gt-TimeSignatureAlg. */
	ERR_clear_error();
	GT_id_gt_time_signature_alg_nid = OBJ_create(
			GT_ID_GT_TIME_SIGNATURE_ALG_OID,
			GT_ID_GT_TIME_SIGNATURE_ALG_SN,
			GT_ID_GT_TIME_SIGNATURE_ALG_LN);
	if (GT_id_gt_time_signature_alg_nid == 0) {
		res = GT_isMallocFailure() ? GT_OUT_OF_MEMORY : GT_CRYPTO_FAILURE;
		goto cleanup;
	}

	GT_id_gt_time_signature_alg = OBJ_nid2obj(GT_id_gt_time_signature_alg_nid);
	if (GT_id_gt_time_signature_alg == NULL) {
		res = GT_CRYPTO_FAILURE;
		goto cleanup;
	}

	res = threadSetup();

cleanup:

	return res;

}
Example #14
0
PKI_OID *PKI_OID_new( char *oid, char *name, char *descr ) {
	PKI_OID *ret = NULL;
	int nid = NID_undef;

	if( !oid && !name && !descr ) return NULL;

	/* Check if the object already exists */
	if( ((nid = OBJ_sn2nid(name)) != NID_undef) ||
		((nid = OBJ_ln2nid(name)) != NID_undef) )
			ret = OBJ_nid2obj(nid);

	if(!ret) {
		/* If it does not exists, then create it */
		(void) OBJ_create( oid, name, descr );

		if( ((nid = OBJ_sn2nid(name)) != NID_undef) ||
			((nid = OBJ_ln2nid(name)) != NID_undef) )
				ret = OBJ_nid2obj(nid);
	}

	/* If successful it returns the new Object, otherwise it
	   return NULL */
	return ( ret );
}
// enables handling of the extension as a string using an appropriate OID
static int _commitmentExt_start() {
	int nid = OBJ_create(COMMITMENT_OID_C, COMMITMENT_OID_SNAME, COMMITMENT_OID_LNAME);
	X509V3_EXT_add_alias(nid, NID_netscape_comment);
	return nid;
}
Example #16
0
DLLEXPORT int
tqsl_init() {
	static char semaphore = 0;
	unsigned int i;
	static char path[TQSL_MAX_PATH_LEN];
#ifdef __WIN32__
	HKEY hkey;
	DWORD dtype;
	DWORD bsize = sizeof path;
	int wval;
#endif

	/* OpenSSL API tends to change between minor version numbers, so make sure
	 * we're using the right version */
	long SSLver = SSLeay();
	int SSLmajor = (SSLver >> 28) & 0xff;
	int SSLminor = (SSLver >> 20) & 0xff;
	int TQSLmajor = (OPENSSL_VERSION_NUMBER >> 28) & 0xff;
	int TQSLminor =  (OPENSSL_VERSION_NUMBER >> 20) & 0xff;

	if (SSLmajor != TQSLmajor || 
		(SSLminor != TQSLminor && 
		(SSLmajor != 9 && SSLminor != 7 && TQSLminor == 6))) {
		tQSL_Error = TQSL_OPENSSL_VERSION_ERROR;
		return 1;
	}
	ERR_clear_error();
	tqsl_getErrorString();	/* Clear the error status */
	if (semaphore)
		return 0;
	ERR_load_crypto_strings();
	OpenSSL_add_all_algorithms();
	for (i = 0; i < (sizeof custom_objects / sizeof custom_objects[0]); i++) {
		if (OBJ_create(custom_objects[i][0], custom_objects[i][1], custom_objects[i][2]) == 0) {
			tQSL_Error = TQSL_OPENSSL_ERROR;
			return 1;
		}
	}
	if (tQSL_BaseDir == NULL) {
		char *cp;
		if ((cp = getenv("TQSLDIR")) != NULL && *cp != '\0')
			strncpy(path, cp, sizeof path);
		else {
#ifdef __WIN32__
			if ((wval = RegOpenKeyEx(HKEY_CURRENT_USER,
				"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
				0, KEY_READ, &hkey)) == ERROR_SUCCESS) {
				wval = RegQueryValueEx(hkey, "AppData", 0, &dtype, (LPBYTE)path, &bsize);
				RegCloseKey(hkey);
			}
			if (wval != ERROR_SUCCESS)
				strcpy(path, "C:");
			strcat(path, "/TrustedQSL");
#else
#ifdef LOTW_SERVER
			strcpy(path, "/var/lotw/tqsl");
#else
			if (getenv("HOME") != NULL) {
				strncpy(path, getenv("HOME"), sizeof path);
				strncat(path, "/", sizeof path - strlen(path));
				strncat(path, ".tqsl", sizeof path - strlen(path));
			} else
				strcpy(path, ".tqsl");
#endif  /* LOTW_SERVER */
#endif  /* WINDOWS */
		}
		if (pmkdir(path, 0700)) {
			strncpy(tQSL_ErrorFile, path, sizeof tQSL_ErrorFile);
			tQSL_Error = TQSL_SYSTEM_ERROR;
			return 1;
		}
		tQSL_BaseDir = path;
	}
	semaphore = 1;
	return 0;
}
Example #17
0
/*
 * We need to replace a standard chunk of PKCS7 signature with one mandated
 * by Authenticode.  Problem is, replacing it just like that and then calling
 * PKCS7_final() would make OpenSSL segfault somewhere in PKCS7_dataFinal().
 * So, instead, we call PKCS7_dataInit(), then put our Authenticode-specific
 * data into BIO it returned, then call PKCS7_dataFinal() - which now somehow
 * does not panic - and _then_ we replace it in the signature.  This technique
 * was used in sbsigntool by Jeremy Kerr, and might have originated in
 * osslsigncode.
 */
static void
magic(PKCS7 *pkcs7, const char *digest, size_t digest_len)
{
	BIO *bio, *t_bio;
	ASN1_TYPE *t;
	ASN1_STRING *s;
	CONF *cnf;
	unsigned char *buf, *tmp;
	char *digest_hex, *magic_conf, *str;
	int len, nid, ok;

	digest_hex = bin2hex(digest, digest_len);

	/*
	 * Construct the SpcIndirectDataContent chunk.
	 */
	nid = OBJ_create("1.3.6.1.4.1.311.2.1.4", NULL, NULL);

	asprintf(&magic_conf, magic_fmt, digest_hex);
	if (magic_conf == NULL)
		err(1, "asprintf");

	bio = BIO_new_mem_buf((void *)magic_conf, -1);
	if (bio == NULL) {
		ERR_print_errors_fp(stderr);
		errx(1, "BIO_new_mem_buf(3) failed");
	}

	cnf = NCONF_new(NULL);
	if (cnf == NULL) {
		ERR_print_errors_fp(stderr);
		errx(1, "NCONF_new(3) failed");
	}

	ok = NCONF_load_bio(cnf, bio, NULL);
	if (ok == 0) {
		ERR_print_errors_fp(stderr);
		errx(1, "NCONF_load_bio(3) failed");
	}

	str = NCONF_get_string(cnf, "default", "asn1");
	if (str == NULL) {
		ERR_print_errors_fp(stderr);
		errx(1, "NCONF_get_string(3) failed");
	}

	t = ASN1_generate_nconf(str, cnf);
	if (t == NULL) {
		ERR_print_errors_fp(stderr);
		errx(1, "ASN1_generate_nconf(3) failed");
	}

	/*
	 * We now have our proprietary piece of ASN.1.  Let's do
	 * the actual signing.
	 */
	len = i2d_ASN1_TYPE(t, NULL);
	tmp = buf = calloc(1, len);
	if (tmp == NULL)
		err(1, "calloc");
	i2d_ASN1_TYPE(t, &tmp);

	/*
	 * We now have contents of 't' stuffed into memory buffer 'buf'.
	 */
	tmp = NULL;
	t = NULL;

	t_bio = PKCS7_dataInit(pkcs7, NULL);
	if (t_bio == NULL) {
		ERR_print_errors_fp(stderr);
		errx(1, "PKCS7_dataInit(3) failed");
	}

	BIO_write(t_bio, buf + 2, len - 2);

	ok = PKCS7_dataFinal(pkcs7, t_bio);
	if (ok == 0) {
		ERR_print_errors_fp(stderr);
		errx(1, "PKCS7_dataFinal(3) failed");
	}

	t = ASN1_TYPE_new();
	s = ASN1_STRING_new();
	ASN1_STRING_set(s, buf, len);
	ASN1_TYPE_set(t, V_ASN1_SEQUENCE, s);

	PKCS7_set0_type_other(pkcs7->d.sign->contents, nid, t);
}
Example #18
0
static int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days)
	{
	X509 *x;
	EVP_PKEY *pk;
	RSA *rsa;
	X509_NAME *name=NULL;
	
	if ((pkeyp == NULL) || (*pkeyp == NULL))
		{
		if ((pk=EVP_PKEY_new()) == NULL)
			{
			abort(); 
			return(0);
			}
		}
	else
		pk= *pkeyp;

	if ((x509p == NULL) || (*x509p == NULL))
		{
		if ((x=X509_new()) == NULL)
			goto err;
		}
	else
		x= *x509p;

    if (bits != 0){
        rsa=RSA_generate_key(bits,RSA_F4,callback,NULL);
        if (!EVP_PKEY_assign_RSA(pk,rsa))
        {
            abort();
            goto err;
        }
        rsa=NULL;
    }

	X509_set_version(x,2);
	ASN1_INTEGER_set(X509_get_serialNumber(x),serial);
	X509_gmtime_adj(X509_get_notBefore(x),0);
	X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
	X509_set_pubkey(x,pk);

	name=X509_get_subject_name(x);

	/* This function creates and adds the entry, working out the
	 * correct string type and performing checks on its length.
	 * Normally we'd check the return value for errors...
	 */
	X509_NAME_add_entry_by_txt(name,"C",
				MBSTRING_ASC,(const unsigned char *) "UK", -1, -1, 0);
	X509_NAME_add_entry_by_txt(name,"CN",
				MBSTRING_ASC, (const unsigned char *) _cert_cn, -1, -1, 0);

	/* Its self signed so set the issuer name to be the same as the
 	 * subject.
	 */
	X509_set_issuer_name(x,name);

	/* Add various extensions: standard extensions */
	add_ext(x, NID_basic_constraints, "critical,CA:TRUE");
	add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign");

	add_ext(x, NID_subject_key_identifier, "hash");

	/* Some Netscape specific extensions */
	add_ext(x, NID_netscape_cert_type, "sslCA");

	add_ext(x, NID_netscape_comment, "example comment extension");


#ifdef CUSTOM_EXT
	/* Maybe even add our own extension based on existing */
	{
		int nid;
		nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
		X509V3_EXT_add_alias(nid, NID_netscape_comment);
		add_ext(x, nid, "example comment alias");
	}
#endif
	
	if (!X509_sign(x,pk,EVP_sha1()))
		goto err;

	*x509p=x;
	*pkeyp=pk;
	return(1);
err:
	return(0);
}
Example #19
0
int32_t mkcert(X509 **x509p, EVP_PKEY **pkeyp, int32_t bits, int32_t serial, int32_t days)
{
    bool bCreatedKey  = false;
    bool bCreatedX509 = false;
        // -----------------
        X509      * x    = NULL;
        EVP_PKEY  * pk   = NULL;
        RSA       * rsa  = NULL;
        X509_NAME * name = NULL;

        if ((pkeyp == NULL) || (*pkeyp == NULL))
        {
            if ((pk = EVP_PKEY_new()) == NULL)
            {
                abort();  // todo
                //return(0); unneeded after abort.
            }
            bCreatedKey = true;
        }
        else
            pk = *pkeyp;
        // -----------------------------------------
        if ((x509p == NULL) || (*x509p == NULL))
        {
            if ((x = X509_new()) == NULL)
            {
                if (bCreatedKey)
                {
                    EVP_PKEY_free(pk);
                }
                return(0);
            }

            bCreatedX509 = true;
        }
        else
            x = *x509p;
        // -----------------------------------------
//		pRsaKey = RSA_generate_key(1024, 0x010001, NULL, NULL);

#ifdef ANDROID
        rsa         = RSA_new();
        BIGNUM * e1 = BN_new();

        if ((NULL == rsa) || (NULL == e1))
            abort(); // todo

//      BN_set_word(e1, 65537);
        BN_set_word(e1, RSA_F4);

        if (!RSA_generate_key_ex(rsa, bits, e1, NULL))
            abort(); // todo

        BN_free(e1);
#else
        rsa = RSA_generate_key(bits, RSA_F4, callback, NULL);
#endif
        // -----------------------------------------
        if (!EVP_PKEY_assign_RSA(pk, rsa))
        {
            abort();  // todo
            //return(0); undeeded after abort.
        }
        // ------------------------------
        rsa = NULL;

        X509_set_version(x, 2);
        ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
        X509_gmtime_adj (X509_get_notBefore(x), 0);
        X509_gmtime_adj (X509_get_notAfter (x), static_cast<int64_t>(60*60*24*days));
        X509_set_pubkey (x, pk);

        name = X509_get_subject_name(x);

        /* This function creates and adds the entry, working out the
         * correct string type and performing checks on its length.
         * Normally we'd check the return value for errors...
         */
        X509_NAME_add_entry_by_txt(name,"C",
                                MBSTRING_ASC,
                                   (const uint8_t *)"UK",
                                   -1, -1, 0);
        X509_NAME_add_entry_by_txt(name,"CN",
                                MBSTRING_ASC,
                                   (const uint8_t *)"OpenSSL Group",
                                   -1, -1, 0);

        /* Its self signed so set the issuer name to be the same as the
         * subject.
         */
        X509_set_issuer_name(x, name);
        // ----------------------------------------------------------------------------
        /* Add various extensions: standard extensions */

        char * szConstraints  = new char[100]();
        char * szKeyUsage     = new char[100]();
        char * szSubjectKeyID = new char[100]();
        char * szCertType     = new char[100]();
        char * szComment      = new char[100]();
        // ----------------------------------------------------------------------------
        opentxs::OTString::safe_strcpy(szConstraints,  "critical,CA:TRUE",             99);
        opentxs::OTString::safe_strcpy(szKeyUsage,     "critical,keyCertSign,cRLSign", 99);
        opentxs::OTString::safe_strcpy(szSubjectKeyID, "hash",                         99);
        opentxs::OTString::safe_strcpy(szCertType,     "sslCA",                        99);
        opentxs::OTString::safe_strcpy(szComment,      "example comment extension",    99);
        // ----------------------------------------------------------------------------
        add_ext(x, NID_basic_constraints,      szConstraints);
        add_ext(x, NID_key_usage,              szKeyUsage);
        add_ext(x, NID_subject_key_identifier, szSubjectKeyID);
        add_ext(x, NID_netscape_cert_type,     szCertType); // Some Netscape specific extensions
        add_ext(x, NID_netscape_comment,       szComment);  // Some Netscape specific extensions
        // ----------------------------------------------------------------------------
        delete [] szConstraints;   szConstraints  = NULL;
        delete [] szKeyUsage;      szKeyUsage     = NULL;
        delete [] szSubjectKeyID;  szSubjectKeyID = NULL;
        delete [] szCertType;      szCertType     = NULL;
        delete [] szComment;       szComment      = NULL;
        // ----------------------------------------------------------------------------

#ifdef CUSTOM_EXT
        // Maybe even add our own extension based on existing
        {
                int32_t nid;
                nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
                X509V3_EXT_add_alias(nid, NID_netscape_comment);
                add_ext(x, nid, "example comment alias");
        }
#endif
        // ------------------------------
        if (!X509_sign(x, pk, EVP_md5()) || // TODO security:  md5 ???
            (NULL == x509p)              ||
            (NULL == pkeyp))
        {
            // ERROR
            //
            if (bCreatedX509)
                X509_free(x);

            // NOTE: not sure if x owns pk, in which case pk is already freed above.
            // Todo: find out and then determine whether or not to uncomment this.
            // (Presumably this would be a rare occurrence anyway.)
            //
//            if (bCreatedKey)
//                EVP_PKEY_free(pk);

            x  = NULL;
            pk = NULL;

            return 0;
        }
        // ------------------------------
        *x509p = x;
        *pkeyp = pk;

        return(1);
}
/**
 * Module activation
 */
static
int
globus_l_openssl_activate(void)
{
    int                                 i;
    int                                 pci_NID;
    int                                 pci_old_NID;
    X509V3_EXT_METHOD *                 pci_x509v3_ext_meth = NULL;
    X509V3_EXT_METHOD *                 pci_old_x509v3_ext_meth = NULL;
    
    SSL_library_init();
    globus_module_activate(GLOBUS_COMMON_MODULE);
    globus_module_activate(GLOBUS_GSI_OPENSSL_ERROR_MODULE);
    mutex_pool = malloc(CRYPTO_num_locks() * sizeof(globus_mutex_t));

    for(i=0;i<CRYPTO_num_locks();i++)
    {
        globus_mutex_init(&(mutex_pool[i]),NULL);
    }

    if (!CRYPTO_get_locking_callback())
    {
        CRYPTO_set_locking_callback(globus_l_openssl_locking_cb);
    }
    if (!CRYPTO_get_id_callback())
    {
        CRYPTO_set_id_callback(globus_l_openssl_thread_id);
    }

    if (OBJ_txt2nid(ANY_LANGUAGE_OID) == 0)
    {
        OBJ_create(ANY_LANGUAGE_OID,
                   ANY_LANGUAGE_SN,
                   ANY_LANGUAGE_LN);
    }

    if (OBJ_txt2nid(IMPERSONATION_PROXY_OID) == 0)
    {
        OBJ_create(IMPERSONATION_PROXY_OID,
                   IMPERSONATION_PROXY_SN,
                   IMPERSONATION_PROXY_LN);
    }

    if (OBJ_txt2nid(INDEPENDENT_PROXY_OID) == 0)
    {
        OBJ_create(INDEPENDENT_PROXY_OID,
                   INDEPENDENT_PROXY_SN,
                   INDEPENDENT_PROXY_LN);
    }

    if (OBJ_txt2nid(LIMITED_PROXY_OID) == 0)
    {
        OBJ_create(LIMITED_PROXY_OID,
                   LIMITED_PROXY_SN,
                   LIMITED_PROXY_LN);
    }

    pci_NID = OBJ_txt2nid(PROXYCERTINFO_OID);
    if (pci_NID == 0)
    {
        pci_NID = OBJ_create(PROXYCERTINFO_OID,
                             PROXYCERTINFO_SN,
                             PROXYCERTINFO_LN);
    }

    pci_old_NID = OBJ_txt2nid(PROXYCERTINFO_OLD_OID);
    if (pci_old_NID == 0)
    {
        pci_old_NID = OBJ_create(PROXYCERTINFO_OLD_OID,
                                 PROXYCERTINFO_OLD_SN,
                                 PROXYCERTINFO_OLD_LN);
    }

    /* this sets the pci NID in the static X509V3_EXT_METHOD struct */
    if (X509V3_EXT_get_nid(pci_NID) == NULL)
    {
        pci_x509v3_ext_meth = PROXYCERTINFO_x509v3_ext_meth();
        pci_x509v3_ext_meth->ext_nid = pci_NID;
        X509V3_EXT_add(pci_x509v3_ext_meth);
    }

    if (X509V3_EXT_get_nid(pci_old_NID) == NULL)
    {
        pci_old_x509v3_ext_meth = PROXYCERTINFO_OLD_x509v3_ext_meth();
        pci_old_x509v3_ext_meth->ext_nid = pci_old_NID;
        X509V3_EXT_add(pci_old_x509v3_ext_meth);
    }

    return GLOBUS_SUCCESS;
}
Example #21
0
int32_t HttpsGenCertReq( HttpsCertReqInfo_t    *pCertReqInfo,
                         unsigned char              *pPrivbuf,
                         unsigned char              *pCertbuf,
                         HttpsCertReqParams_t  *pParams )
{
  EVP_PKEY                  *pkey         = NULL;
  HX509Req_t                *preq         = NULL;
#ifdef OPENSSL_9_7
  const  EVP_MD             *pDigest;
#else
  EVP_MD                    *pDigest      = NULL;
#endif /*OPENSSL_9_7*/
  int32_t                   iRetVal;
  unsigned char                  aSubAltName[HTTPS_PARAMS_SUB_NAME_LEN];
  bool                   bFlag         = FALSE;
  STACK_OF(X509_EXTENSION)  *skExtensions = NULL;
  X509_EXTENSION            *pSubExt      = NULL;
  unsigned char                  ucCT;
  int32_t                   uileng;

  /**
   * Input Validations...
   */
  if (pCertReqInfo == NULL)
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Invalid parameters\n");
    return OF_FAILURE;
  }

  /**
   * Allocate space for the public-private key pair..
   */

  if ((pkey = EVP_PKEY_new()) == NULL)
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: MemAlloc failure\n");
    return OF_FAILURE;
  }

  /**
   * Generate a public-private key pair..
   */
  switch (pCertReqInfo->usCertType)
  {
  case RSA_MD5:
  case RSA_SHA1:
    if ((pCertReqInfo->cr_params.rsa_params.usNumBits < MIN_KEY_LENGTH))
    {
      Trace(HTTPS_ID, TRACE_SEVERE,
            "HttpsGenCertReq : Invalid RSA parameters\n");
      EVP_PKEY_free(pkey);
      return OF_FAILURE;
    }

    if (!EVP_PKEY_assign_RSA(pkey,
            RSA_generate_key(pCertReqInfo->cr_params.rsa_params.usNumBits,
            0x10001, NULL, NULL)))
    {
      Trace(HTTPS_ID, TRACE_SEVERE,
            "HttpsGenCertReq: EVP_PKEY assign failed\n");
      EVP_PKEY_free(pkey);
      return OF_FAILURE;
    }

    ucCT='r';

    if (pCertReqInfo->usCertType == RSA_MD5)
    {
      pDigest = (EVP_MD *) EVP_md5();
    }
    else
    {
      pDigest = (EVP_MD *) EVP_sha1();
    }

    break;
  default:
    Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Invalid certificate type\n");
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * Prepare the Certificate Request..
   */
  if ((preq = HttpsCertReqNew()) == NULL)
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: X509_req_new failed\n");
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * Version Number..
   */
  if (!ASN1_INTEGER_set(preq->req_info->version, 0L))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: ASN1_INTEGER_set failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * Subject Name...Filled with two RDNs...
   */

  /**
   * RDN # 1 : Country Name...
   */

  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->ucCn, NID_countryName, 2, 2))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

#ifdef OPENSSL_9_7
  if (NID_postalCode == 0)
  {
    NID_postalCode = OBJ_create("2.5.4.17", "2.5.4.17",
                                "postal code attribute");
  }
#endif

  /**
   * RDN #New::2: Postal code...
   */
  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->aPostalCode, NID_postalCode, 0,
                          10))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * RDN #3: State..
   */
  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->aState, NID_stateOrProvinceName,
                          0, 50))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * RDN #New::4: Locality Name...
   */
  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->aCity, NID_localityName, 0, 50))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * RDN #5 : Organization ..
   */
  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->aOrg, NID_organizationName,
                          0, 50))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * RDN #6 : Department ..
   */
  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->aDept, NID_organizationalUnitName,
                          0, 50))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * RDN #7 : Common Name (Subject)...
   */
  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->ucSub, NID_commonName, 0, 50))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  of_memset( aSubAltName, 0, HTTPS_PARAMS_SUB_NAME_LEN);

  if (strlen((char *) pParams->aIpAddr))
  {
    of_strcat((char *) aSubAltName, "IP:");
    of_strcat((char *) aSubAltName, (char *) pParams->aIpAddr);
    bFlag = TRUE;
  }

  if (strlen((char *) pParams->aEmailId))
  {
    if (bFlag)
    {
      of_strcat((char *) aSubAltName, ",email:");
    }
    else
    {
      of_strcat((char *) aSubAltName, "email:");
    }

    of_strcat((char *) aSubAltName, (char *) pParams->aEmailId);
    bFlag = TRUE;
  }

  if (strlen((char *) pParams->aDomain))
  {
    if (bFlag)
    {
      of_strcat((char *) aSubAltName, ",DNS:");
    }
    else
    {
      of_strcat((char *) aSubAltName, "DNS:");
    }

    of_strcat((char *) aSubAltName, (char *) pParams->aDomain);
    bFlag = TRUE;
  }

  /**
   * Adding subject alt name extension to the request.
   */
  if ( of_strlen((char *) aSubAltName))
  {
    skExtensions = sk_X509_EXTENSION_new_null();

    if (skExtensions == NULL)
    {
      Trace(HTTPS_ID, TRACE_SEVERE,
            "HttpsGenCertReq:: sk_X509_EXTENSION_new_null failed\n");
      HttpsCertReqFree(preq);
      EVP_PKEY_free(pkey);
      return OF_FAILURE;
    }
    pSubExt = X509V3_EXT_conf_nid(NULL, NULL, NID_subject_alt_name,
                                  (char *) aSubAltName);

    if (pSubExt)
    {
      sk_X509_EXTENSION_push(skExtensions, pSubExt);
    }

    iRetVal = X509_REQ_add_extensions(preq, skExtensions);

    if (iRetVal == 0)
    {
      Trace(HTTPS_ID, TRACE_SEVERE,
            "HttpsGenCertReq:: X509_REQ_add_extensions failed\n");
      HttpsCertReqFree(preq);
      EVP_PKEY_free(pkey);
      return OF_FAILURE;
    }

    sk_X509_EXTENSION_pop_free(skExtensions, X509_EXTENSION_free);
  } /* strlen sub alt */

  /**
   * Set the public key..
   */
  if (!X509_REQ_set_pubkey(preq, pkey))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: X509_REQ_sign failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * Sign the CertReq Info..
   */
  if (!X509_REQ_sign(preq, pkey, pDigest))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: X509_REQ_sign failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * Write the Private Key into the file...
   */
  if (HttpsWritetoFile(pPrivbuf, HTTPS_PRIV_KEY, pkey, ucCT,
                       pParams->aIdName))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: HttpsWritetoFile failed #1\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * Write the Certificate Request into the file...
   */
  if (HttpsWritetoFile(pCertbuf, HTTPS_CERT_REQ, preq, ucCT,
                       pParams->aIdName))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: HttpsWritetoFile failed #2\n");
    HttpsDeleteCerts(pParams->aIdName, 's');
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  uileng=strlen((char *) pCertbuf);

  if (uileng > 2047)
  {
    Trace(HTTPS_ID, TRACE_SEVERE, "pCertbuf length exceeds 2k\n");
    HttpsDeleteCerts(pParams->aIdName, 's');
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  Trace(HTTPS_ID, TRACE_INFO, "Generation of Certificate Request done\n");
  HttpsCertReqFree(preq);
  EVP_PKEY_free(pkey);
  return OF_SUCCESS;
} /* HttpsGenCertReq() */
Example #22
0
int x509_main(int argc, char **argv)
{
    ASN1_INTEGER *sno = NULL;
    ASN1_OBJECT *objtmp;
    BIO *out = NULL;
    CONF *extconf = NULL;
    EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL;
    STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
    STACK_OF(OPENSSL_STRING) *sigopts = NULL;
    X509 *x = NULL, *xca = NULL;
    X509_REQ *req = NULL, *rq = NULL;
    X509_STORE *ctx = NULL;
    const EVP_MD *digest = NULL;
    char *CAkeyfile = NULL, *CAserial = NULL, *fkeyfile = NULL, *alias = NULL;
    char *checkhost = NULL, *checkemail = NULL, *checkip = NULL;
    char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL;
    char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL;
    char buf[256], *prog;
    int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = 0;
    int C = 0, CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM;
    int fingerprint = 0, reqfile = 0, need_rand = 0, checkend = 0;
    int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM;
    int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0;
    int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0;
    int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0;
    int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0;
    int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0;
    int checkoffset = 0, enddate = 0;
    unsigned long nmflag = 0, certflag = 0;
    OPTION_CHOICE o;
    ENGINE *e = NULL;
#ifndef OPENSSL_NO_MD5
    int subject_hash_old = 0, issuer_hash_old = 0;
#endif

    ctx = X509_STORE_new();
    if (ctx == NULL)
        goto end;
    X509_STORE_set_verify_cb(ctx, callb);

    prog = opt_init(argc, argv, x509_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(x509_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat))
                goto opthelp;
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat))
                goto opthelp;
            break;
        case OPT_CAFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAformat))
                goto opthelp;
            break;
        case OPT_CAKEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAkeyformat))
                goto opthelp;
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_REQ:
            reqfile = need_rand = 1;
            break;

        case OPT_SIGOPT:
            if (!sigopts)
                sigopts = sk_OPENSSL_STRING_new_null();
            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
                goto opthelp;
            break;
#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
        case OPT_FORCE_VERSION:
            force_version = atoi(opt_arg()) - 1;
            break;
#endif
        case OPT_DAYS:
            days = atoi(opt_arg());
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_EXTFILE:
            extfile = opt_arg();
            break;
        case OPT_EXTENSIONS:
            extsect = opt_arg();
            break;
        case OPT_SIGNKEY:
            keyfile = opt_arg();
            sign_flag = ++num;
            need_rand = 1;
            break;
        case OPT_CA:
            CAfile = opt_arg();
            CA_flag = ++num;
            need_rand = 1;
            break;
        case OPT_CAKEY:
            CAkeyfile = opt_arg();
            break;
        case OPT_CASERIAL:
            CAserial = opt_arg();
            break;
        case OPT_SET_SERIAL:
            if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL)
                goto opthelp;
            break;
        case OPT_FORCE_PUBKEY:
            fkeyfile = opt_arg();
            break;
        case OPT_ADDTRUST:
            if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
                BIO_printf(bio_err,
                           "%s: Invalid trust object value %s\n",
                           prog, opt_arg());
                goto opthelp;
            }
            if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL)
                goto end;
            sk_ASN1_OBJECT_push(trust, objtmp);
            trustout = 1;
            break;
        case OPT_ADDREJECT:
            if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
                BIO_printf(bio_err,
                           "%s: Invalid reject object value %s\n",
                           prog, opt_arg());
                goto opthelp;
            }
            if (reject == NULL
                && (reject = sk_ASN1_OBJECT_new_null()) == NULL)
                goto end;
            sk_ASN1_OBJECT_push(reject, objtmp);
            trustout = 1;
            break;
        case OPT_SETALIAS:
            alias = opt_arg();
            trustout = 1;
            break;
        case OPT_CERTOPT:
            if (!set_cert_ex(&certflag, opt_arg()))
                goto opthelp;
            break;
        case OPT_NAMEOPT:
            if (!set_name_ex(&nmflag, opt_arg()))
                goto opthelp;
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_C:
            C = ++num;
            break;
        case OPT_EMAIL:
            email = ++num;
            break;
        case OPT_OCSP_URI:
            ocsp_uri = ++num;
            break;
        case OPT_SERIAL:
            serial = ++num;
            break;
        case OPT_NEXT_SERIAL:
            next_serial = ++num;
            break;
        case OPT_MODULUS:
            modulus = ++num;
            break;
        case OPT_PUBKEY:
            pubkey = ++num;
            break;
        case OPT_X509TOREQ:
            x509req = ++num;
            break;
        case OPT_TEXT:
            text = ++num;
            break;
        case OPT_SUBJECT:
            subject = ++num;
            break;
        case OPT_ISSUER:
            issuer = ++num;
            break;
        case OPT_FINGERPRINT:
            fingerprint = ++num;
            break;
        case OPT_HASH:
            subject_hash = ++num;
            break;
        case OPT_ISSUER_HASH:
            issuer_hash = ++num;
            break;
        case OPT_PURPOSE:
            pprint = ++num;
            break;
        case OPT_STARTDATE:
            startdate = ++num;
            break;
        case OPT_ENDDATE:
            enddate = ++num;
            break;
        case OPT_NOOUT:
            noout = ++num;
            break;
        case OPT_NOCERT:
            nocert = 1;
            break;
        case OPT_TRUSTOUT:
            trustout = 1;
            break;
        case OPT_CLRTRUST:
            clrtrust = ++num;
            break;
        case OPT_CLRREJECT:
            clrreject = ++num;
            break;
        case OPT_ALIAS:
            aliasout = ++num;
            break;
        case OPT_CACREATESERIAL:
            CA_createserial = ++num;
            break;
        case OPT_CLREXT:
            clrext = 1;
            break;
        case OPT_OCSPID:
            ocspid = ++num;
            break;
        case OPT_BADSIG:
            badsig = 1;
            break;
#ifndef OPENSSL_NO_MD5
        case OPT_SUBJECT_HASH_OLD:
            subject_hash_old = ++num;
            break;
        case OPT_ISSUER_HASH_OLD:
            issuer_hash_old = ++num;
            break;
#endif
        case OPT_DATES:
            startdate = ++num;
            enddate = ++num;
            break;
        case OPT_CHECKEND:
            checkoffset = atoi(opt_arg());
            checkend = 1;
            break;
        case OPT_CHECKHOST:
            checkhost = opt_arg();
            break;
        case OPT_CHECKEMAIL:
            checkemail = opt_arg();
            break;
        case OPT_CHECKIP:
            checkip = opt_arg();
            break;
        case OPT_MD:
            if (!opt_md(opt_unknown(), &digest))
                goto opthelp;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();
    if (argc != 0) {
        BIO_printf(bio_err, "%s: Unknown parameter %s\n", prog, argv[0]);
        goto opthelp;
    }

    out = bio_open_default(outfile, "w");
    if (out == NULL)
        goto end;

    if (need_rand)
        app_RAND_load_file(NULL, 0);

    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
        BIO_printf(bio_err, "Error getting password\n");
        goto end;
    }

    if (!X509_STORE_set_default_paths(ctx)) {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (fkeyfile) {
        fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key");
        if (fkey == NULL)
            goto end;
    }

    if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) {
        CAkeyfile = CAfile;
    } else if ((CA_flag) && (CAkeyfile == NULL)) {
        BIO_printf(bio_err,
                   "need to specify a CAkey if using the CA command\n");
        goto end;
    }

    if (extfile) {
        long errorline = -1;
        X509V3_CTX ctx2;
        extconf = NCONF_new(NULL);
        if (!NCONF_load(extconf, extfile, &errorline)) {
            if (errorline <= 0)
                BIO_printf(bio_err,
                           "error loading the config file '%s'\n", extfile);
            else
                BIO_printf(bio_err,
                           "error on line %ld of config file '%s'\n",
                           errorline, extfile);
            goto end;
        }
        if (!extsect) {
            extsect = NCONF_get_string(extconf, "default", "extensions");
            if (!extsect) {
                ERR_clear_error();
                extsect = "default";
            }
        }
        X509V3_set_ctx_test(&ctx2);
        X509V3_set_nconf(&ctx2, extconf);
        if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) {
            BIO_printf(bio_err,
                       "Error Loading extension section %s\n", extsect);
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (reqfile) {
        EVP_PKEY *pkey;
        BIO *in;

        if (!sign_flag && !CA_flag) {
            BIO_printf(bio_err, "We need a private key to sign with\n");
            goto end;
        }
        in = bio_open_default(infile, "r");
        if (in == NULL)
            goto end;
        req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
        BIO_free(in);

        if (req == NULL) {
            ERR_print_errors(bio_err);
            goto end;
        }

        if ((req->req_info == NULL) ||
            (req->req_info->pubkey == NULL) ||
            (req->req_info->pubkey->public_key == NULL) ||
            (req->req_info->pubkey->public_key->data == NULL)) {
            BIO_printf(bio_err,
                       "The certificate request appears to corrupted\n");
            BIO_printf(bio_err, "It does not contain a public key\n");
            goto end;
        }
        if ((pkey = X509_REQ_get_pubkey(req)) == NULL) {
            BIO_printf(bio_err, "error unpacking public key\n");
            goto end;
        }
        i = X509_REQ_verify(req, pkey);
        EVP_PKEY_free(pkey);
        if (i < 0) {
            BIO_printf(bio_err, "Signature verification error\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (i == 0) {
            BIO_printf(bio_err,
                       "Signature did not match the certificate request\n");
            goto end;
        } else
            BIO_printf(bio_err, "Signature ok\n");

        print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
                   nmflag);

        if ((x = X509_new()) == NULL)
            goto end;

        if (sno == NULL) {
            sno = ASN1_INTEGER_new();
            if (!sno || !rand_serial(NULL, sno))
                goto end;
            if (!X509_set_serialNumber(x, sno))
                goto end;
            ASN1_INTEGER_free(sno);
            sno = NULL;
        } else if (!X509_set_serialNumber(x, sno))
            goto end;

        if (!X509_set_issuer_name(x, req->req_info->subject))
            goto end;
        if (!X509_set_subject_name(x, req->req_info->subject))
            goto end;

        X509_gmtime_adj(X509_get_notBefore(x), 0);
        X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL);
        if (fkey)
            X509_set_pubkey(x, fkey);
        else {
            pkey = X509_REQ_get_pubkey(req);
            X509_set_pubkey(x, pkey);
            EVP_PKEY_free(pkey);
        }
    } else
        x = load_cert(infile, informat, NULL, e, "Certificate");

    if (x == NULL)
        goto end;
    if (CA_flag) {
        xca = load_cert(CAfile, CAformat, NULL, e, "CA Certificate");
        if (xca == NULL)
            goto end;
    }

    if (!noout || text || next_serial) {
        OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");

    }

    if (alias)
        X509_alias_set1(x, (unsigned char *)alias, -1);

    if (clrtrust)
        X509_trust_clear(x);
    if (clrreject)
        X509_reject_clear(x);

    if (trust) {
        for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
            objtmp = sk_ASN1_OBJECT_value(trust, i);
            X509_add1_trust_object(x, objtmp);
        }
    }

    if (reject) {
        for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
            objtmp = sk_ASN1_OBJECT_value(reject, i);
            X509_add1_reject_object(x, objtmp);
        }
    }

    if (num) {
        for (i = 1; i <= num; i++) {
            if (issuer == i) {
                print_name(out, "issuer= ", X509_get_issuer_name(x), nmflag);
            } else if (subject == i) {
                print_name(out, "subject= ",
                           X509_get_subject_name(x), nmflag);
            } else if (serial == i) {
                BIO_printf(out, "serial=");
                i2a_ASN1_INTEGER(out, X509_get_serialNumber(x));
                BIO_printf(out, "\n");
            } else if (next_serial == i) {
                BIGNUM *bnser;
                ASN1_INTEGER *ser;
                ser = X509_get_serialNumber(x);
                bnser = ASN1_INTEGER_to_BN(ser, NULL);
                if (!bnser)
                    goto end;
                if (!BN_add_word(bnser, 1))
                    goto end;
                ser = BN_to_ASN1_INTEGER(bnser, NULL);
                if (!ser)
                    goto end;
                BN_free(bnser);
                i2a_ASN1_INTEGER(out, ser);
                ASN1_INTEGER_free(ser);
                BIO_puts(out, "\n");
            } else if ((email == i) || (ocsp_uri == i)) {
                int j;
                STACK_OF(OPENSSL_STRING) *emlst;
                if (email == i)
                    emlst = X509_get1_email(x);
                else
                    emlst = X509_get1_ocsp(x);
                for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
                    BIO_printf(out, "%s\n",
                               sk_OPENSSL_STRING_value(emlst, j));
                X509_email_free(emlst);
            } else if (aliasout == i) {
                unsigned char *alstr;
                alstr = X509_alias_get0(x, NULL);
                if (alstr)
                    BIO_printf(out, "%s\n", alstr);
                else
                    BIO_puts(out, "<No Alias>\n");
            } else if (subject_hash == i) {
                BIO_printf(out, "%08lx\n", X509_subject_name_hash(x));
            }
#ifndef OPENSSL_NO_MD5
            else if (subject_hash_old == i) {
                BIO_printf(out, "%08lx\n", X509_subject_name_hash_old(x));
            }
#endif
            else if (issuer_hash == i) {
                BIO_printf(out, "%08lx\n", X509_issuer_name_hash(x));
            }
#ifndef OPENSSL_NO_MD5
            else if (issuer_hash_old == i) {
                BIO_printf(out, "%08lx\n", X509_issuer_name_hash_old(x));
            }
#endif
            else if (pprint == i) {
                X509_PURPOSE *ptmp;
                int j;
                BIO_printf(out, "Certificate purposes:\n");
                for (j = 0; j < X509_PURPOSE_get_count(); j++) {
                    ptmp = X509_PURPOSE_get0(j);
                    purpose_print(out, x, ptmp);
                }
            } else if (modulus == i) {
                EVP_PKEY *pkey;

                pkey = X509_get_pubkey(x);
                if (pkey == NULL) {
                    BIO_printf(bio_err, "Modulus=unavailable\n");
                    ERR_print_errors(bio_err);
                    goto end;
                }
                BIO_printf(out, "Modulus=");
#ifndef OPENSSL_NO_RSA
                if (pkey->type == EVP_PKEY_RSA)
                    BN_print(out, pkey->pkey.rsa->n);
                else
#endif
#ifndef OPENSSL_NO_DSA
                if (pkey->type == EVP_PKEY_DSA)
                    BN_print(out, pkey->pkey.dsa->pub_key);
                else
#endif
                    BIO_printf(out, "Wrong Algorithm type");
                BIO_printf(out, "\n");
                EVP_PKEY_free(pkey);
            } else if (pubkey == i) {
                EVP_PKEY *pkey;

                pkey = X509_get_pubkey(x);
                if (pkey == NULL) {
                    BIO_printf(bio_err, "Error getting public key\n");
                    ERR_print_errors(bio_err);
                    goto end;
                }
                PEM_write_bio_PUBKEY(out, pkey);
                EVP_PKEY_free(pkey);
            } else if (C == i) {
                unsigned char *d;
                char *m;
                int len;

                X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf);
                BIO_printf(out, "/*\n"
                                " * Subject: %s\n", buf);

                m = X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf);
                BIO_printf(out, " * Issuer:  %s\n"
                                " */\n", buf);

                len = i2d_X509(x, NULL);
                m = app_malloc(len, "x509 name buffer");
                d = (unsigned char *)m;
                len = i2d_X509_NAME(X509_get_subject_name(x), &d);
                print_array(out, "the_subject_name", len, (unsigned char *)m);
                d = (unsigned char *)m;
                len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d);
                print_array(out, "the_public_key", len, (unsigned char *)m);
                d = (unsigned char *)m;
                len = i2d_X509(x, &d);
                print_array(out, "the_certificate", len, (unsigned char *)m);
                OPENSSL_free(m);
            } else if (text == i) {
                X509_print_ex(out, x, nmflag, certflag);
            } else if (startdate == i) {
                BIO_puts(out, "notBefore=");
                ASN1_TIME_print(out, X509_get_notBefore(x));
                BIO_puts(out, "\n");
            } else if (enddate == i) {
                BIO_puts(out, "notAfter=");
                ASN1_TIME_print(out, X509_get_notAfter(x));
                BIO_puts(out, "\n");
            } else if (fingerprint == i) {
                int j;
                unsigned int n;
                unsigned char md[EVP_MAX_MD_SIZE];
                const EVP_MD *fdig = digest;

                if (!fdig)
                    fdig = EVP_sha1();

                if (!X509_digest(x, fdig, md, &n)) {
                    BIO_printf(bio_err, "out of memory\n");
                    goto end;
                }
                BIO_printf(out, "%s Fingerprint=",
                           OBJ_nid2sn(EVP_MD_type(fdig)));
                for (j = 0; j < (int)n; j++) {
                    BIO_printf(out, "%02X%c", md[j], (j + 1 == (int)n)
                               ? '\n' : ':');
                }
            }

            /* should be in the library */
            else if ((sign_flag == i) && (x509req == 0)) {
                BIO_printf(bio_err, "Getting Private key\n");
                if (Upkey == NULL) {
                    Upkey = load_key(keyfile, keyformat, 0,
                                     passin, e, "Private key");
                    if (Upkey == NULL)
                        goto end;
                }

                assert(need_rand);
                if (!sign(x, Upkey, days, clrext, digest, extconf, extsect))
                    goto end;
            } else if (CA_flag == i) {
                BIO_printf(bio_err, "Getting CA Private Key\n");
                if (CAkeyfile != NULL) {
                    CApkey = load_key(CAkeyfile, CAkeyformat,
                                      0, passin, e, "CA Private Key");
                    if (CApkey == NULL)
                        goto end;
                }

                assert(need_rand);
                if (!x509_certify(ctx, CAfile, digest, x, xca,
                                  CApkey, sigopts,
                                  CAserial, CA_createserial, days, clrext,
                                  extconf, extsect, sno, reqfile))
                    goto end;
            } else if (x509req == i) {
                EVP_PKEY *pk;

                BIO_printf(bio_err, "Getting request Private Key\n");
                if (keyfile == NULL) {
                    BIO_printf(bio_err, "no request key file specified\n");
                    goto end;
                } else {
                    pk = load_key(keyfile, keyformat, 0,
                                  passin, e, "request key");
                    if (pk == NULL)
                        goto end;
                }

                BIO_printf(bio_err, "Generating certificate request\n");

                rq = X509_to_X509_REQ(x, pk, digest);
                EVP_PKEY_free(pk);
                if (rq == NULL) {
                    ERR_print_errors(bio_err);
                    goto end;
                }
                if (!noout) {
                    X509_REQ_print(out, rq);
                    PEM_write_bio_X509_REQ(out, rq);
                }
                noout = 1;
            } else if (ocspid == i) {
                X509_ocspid_print(out, x);
            }
        }
    }

    if (checkend) {
        time_t tcheck = time(NULL) + checkoffset;

        if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) {
            BIO_printf(out, "Certificate will expire\n");
            ret = 1;
        } else {
            BIO_printf(out, "Certificate will not expire\n");
            ret = 0;
        }
        goto end;
    }

    print_cert_checks(out, x, checkhost, checkemail, checkip);

    if (noout || nocert) {
        ret = 0;
        goto end;
    }

    if (badsig)
        x->signature->data[x->signature->length - 1] ^= 0x1;

    if (outformat == FORMAT_ASN1)
        i = i2d_X509_bio(out, x);
    else if (outformat == FORMAT_PEM) {
        if (trustout)
            i = PEM_write_bio_X509_AUX(out, x);
        else
            i = PEM_write_bio_X509(out, x);
    } else if (outformat == FORMAT_NETSCAPE) {
        NETSCAPE_X509 nx;
        ASN1_OCTET_STRING hdr;

        hdr.data = (unsigned char *)NETSCAPE_CERT_HDR;
        hdr.length = strlen(NETSCAPE_CERT_HDR);
        nx.header = &hdr;
        nx.cert = x;

        i = ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509), out, &nx);
    } else {
        BIO_printf(bio_err, "bad output format specified for outfile\n");
        goto end;
    }
    if (!i) {
        BIO_printf(bio_err, "unable to write certificate\n");
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;
 end:
    if (need_rand)
        app_RAND_write_file(NULL);
    OBJ_cleanup();
    NCONF_free(extconf);
    BIO_free_all(out);
    X509_STORE_free(ctx);
    X509_REQ_free(req);
    X509_free(x);
    X509_free(xca);
    EVP_PKEY_free(Upkey);
    EVP_PKEY_free(CApkey);
    EVP_PKEY_free(fkey);
    sk_OPENSSL_STRING_free(sigopts);
    X509_REQ_free(rq);
    ASN1_INTEGER_free(sno);
    sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
    sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
    OPENSSL_free(passin);
    return (ret);
}
Example #23
0
int mkreq(X509_REQ **req, EVP_PKEY **pkeyp, int bits, int serial, int days)
	{
	X509_REQ *x;
	EVP_PKEY *pk;
	RSA *rsa;
	X509_NAME *name=NULL;
	STACK_OF(X509_EXTENSION) *exts = NULL;
	
	if ((pk=EVP_PKEY_new()) == NULL)
		goto err;

	if ((x=X509_REQ_new()) == NULL)
		goto err;

	rsa=RSA_generate_key(bits,RSA_F4,callback,NULL);
	if (!EVP_PKEY_assign_RSA(pk,rsa))
		goto err;

	rsa=NULL;

	X509_REQ_set_pubkey(x,pk);

	name=X509_REQ_get_subject_name(x);

	/* This function creates and adds the entry, working out the
	 * correct string type and performing checks on its length.
	 * Normally we'd check the return value for errors...
	 */
	X509_NAME_add_entry_by_txt(name,"C",
				MBSTRING_ASC, "UK", -1, -1, 0);
	X509_NAME_add_entry_by_txt(name,"CN",
				MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);

#ifdef REQUEST_EXTENSIONS
	/* Certificate requests can contain extensions, which can be used
	 * to indicate the extensions the requestor would like added to 
	 * their certificate. CAs might ignore them however or even choke
	 * if they are present.
	 */

	/* For request extensions they are all packed in a single attribute.
	 * We save them in a STACK and add them all at once later...
	 */

	exts = sk_X509_EXTENSION_new_null();
	/* Standard extenions */

	add_ext(exts, NID_key_usage, "critical,digitalSignature,keyEncipherment");

	/* This is a typical use for request extensions: requesting a value for
	 * subject alternative name.
	 */

	add_ext(exts, NID_subject_alt_name, "email:[email protected]");

	/* Some Netscape specific extensions */
	add_ext(exts, NID_netscape_cert_type, "client,email");



#ifdef CUSTOM_EXT
	/* Maybe even add our own extension based on existing */
	{
		int nid;
		nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
		X509V3_EXT_add_alias(nid, NID_netscape_comment);
		add_ext(x, nid, "example comment alias");
	}
#endif

	/* Now we've created the extensions we add them to the request */

	X509_REQ_add_extensions(x, exts);

	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);

#endif
	
	if (!X509_REQ_sign(x,pk,EVP_md5()))
		goto err;

	*req=x;
	*pkeyp=pk;
	return(1);
err:
	return(0);
	}
Example #24
0
int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	int ret=1;
	X509_REQ *req=NULL;
	X509 *x=NULL,*xca=NULL;
	ASN1_OBJECT *objtmp;
	STACK_OF(OPENSSL_STRING) *sigopts = NULL;
	EVP_PKEY *Upkey=NULL,*CApkey=NULL;
	ASN1_INTEGER *sno = NULL;
	int i,num,badops=0;
	BIO *out=NULL;
	BIO *STDout=NULL;
	STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
	int informat,outformat,keyformat,CAformat,CAkeyformat;
	char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
	char *CAkeyfile=NULL,*CAserial=NULL;
	char *alias=NULL;
	int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0;
	int next_serial=0;
	int subject_hash=0,issuer_hash=0,ocspid=0;
#ifndef OPENSSL_NO_MD5
	int subject_hash_old=0,issuer_hash_old=0;
#endif
	int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
	int ocsp_uri=0;
	int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
	int C=0;
	int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
	int pprint = 0;
	const char **pp;
	X509_STORE *ctx=NULL;
	X509_REQ *rq=NULL;
	int fingerprint=0;
	char buf[256];
	const EVP_MD *md_alg,*digest=NULL;
	CONF *extconf = NULL;
	char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
	int need_rand = 0;
	int checkend=0,checkoffset=0;
	unsigned long nmflag = 0, certflag = 0;
#ifndef OPENSSL_NO_ENGINE
	char *engine=NULL;
#endif

	reqfile=0;

	apps_startup();

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;
	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	STDout = BIO_push(tmpbio, STDout);
	}
#endif

	informat=FORMAT_PEM;
	outformat=FORMAT_PEM;
	keyformat=FORMAT_PEM;
	CAformat=FORMAT_PEM;
	CAkeyformat=FORMAT_PEM;

	ctx=X509_STORE_new();
	if (ctx == NULL) goto end;
	X509_STORE_set_verify_cb(ctx,callb);

	argc--;
	argv++;
	num=0;
	while (argc >= 1)
		{
		if 	(strcmp(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-outform") == 0)
			{
			if (--argc < 1) goto bad;
			outformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-keyform") == 0)
			{
			if (--argc < 1) goto bad;
			keyformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-req") == 0)
			{
			reqfile=1;
			need_rand = 1;
			}
		else if (strcmp(*argv,"-CAform") == 0)
			{
			if (--argc < 1) goto bad;
			CAformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-CAkeyform") == 0)
			{
			if (--argc < 1) goto bad;
			CAkeyformat=str2fmt(*(++argv));
			}
		else if (strcmp(*argv,"-sigopt") == 0)
			{
			if (--argc < 1)
				goto bad;
			if (!sigopts)
				sigopts = sk_OPENSSL_STRING_new_null();
			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
				goto bad;
			}
		else if (strcmp(*argv,"-days") == 0)
			{
			if (--argc < 1) goto bad;
			days=atoi(*(++argv));
			if (days == 0)
				{
				BIO_printf(STDout,"bad number of days\n");
				goto bad;
				}
			}
		else if (strcmp(*argv,"-passin") == 0)
			{
			if (--argc < 1) goto bad;
			passargin= *(++argv);
			}
		else if (strcmp(*argv,"-extfile") == 0)
			{
			if (--argc < 1) goto bad;
			extfile= *(++argv);
			}
		else if (strcmp(*argv,"-extensions") == 0)
			{
			if (--argc < 1) goto bad;
			extsect= *(++argv);
			}
		else if (strcmp(*argv,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
		else if (strcmp(*argv,"-signkey") == 0)
			{
			if (--argc < 1) goto bad;
			keyfile= *(++argv);
			sign_flag= ++num;
			need_rand = 1;
			}
		else if (strcmp(*argv,"-CA") == 0)
			{
			if (--argc < 1) goto bad;
			CAfile= *(++argv);
			CA_flag= ++num;
			need_rand = 1;
			}
		else if (strcmp(*argv,"-CAkey") == 0)
			{
			if (--argc < 1) goto bad;
			CAkeyfile= *(++argv);
			}
		else if (strcmp(*argv,"-CAserial") == 0)
			{
			if (--argc < 1) goto bad;
			CAserial= *(++argv);
			}
		else if (strcmp(*argv,"-set_serial") == 0)
			{
			if (--argc < 1) goto bad;
			if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
				goto bad;
			}
		else if (strcmp(*argv,"-addtrust") == 0)
			{
			if (--argc < 1) goto bad;
			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
				{
				BIO_printf(bio_err,
					"Invalid trust object value %s\n", *argv);
				goto bad;
				}
			if (!trust) trust = sk_ASN1_OBJECT_new_null();
			sk_ASN1_OBJECT_push(trust, objtmp);
			trustout = 1;
			}
		else if (strcmp(*argv,"-addreject") == 0)
			{
			if (--argc < 1) goto bad;
			if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
				{
				BIO_printf(bio_err,
					"Invalid reject object value %s\n", *argv);
				goto bad;
				}
			if (!reject) reject = sk_ASN1_OBJECT_new_null();
			sk_ASN1_OBJECT_push(reject, objtmp);
			trustout = 1;
			}
		else if (strcmp(*argv,"-setalias") == 0)
			{
			if (--argc < 1) goto bad;
			alias= *(++argv);
			trustout = 1;
			}
		else if (strcmp(*argv,"-certopt") == 0)
			{
			if (--argc < 1) goto bad;
			if (!set_cert_ex(&certflag, *(++argv))) goto bad;
			}
		else if (strcmp(*argv,"-nameopt") == 0)
			{
			if (--argc < 1) goto bad;
			if (!set_name_ex(&nmflag, *(++argv))) goto bad;
			}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine= *(++argv);
			}
#endif
		else if (strcmp(*argv,"-C") == 0)
			C= ++num;
		else if (strcmp(*argv,"-email") == 0)
			email= ++num;
		else if (strcmp(*argv,"-ocsp_uri") == 0)
			ocsp_uri= ++num;
		else if (strcmp(*argv,"-serial") == 0)
			serial= ++num;
		else if (strcmp(*argv,"-next_serial") == 0)
			next_serial= ++num;
		else if (strcmp(*argv,"-modulus") == 0)
			modulus= ++num;
		else if (strcmp(*argv,"-pubkey") == 0)
			pubkey= ++num;
		else if (strcmp(*argv,"-x509toreq") == 0)
			x509req= ++num;
		else if (strcmp(*argv,"-text") == 0)
			text= ++num;
		else if (strcmp(*argv,"-hash") == 0
			|| strcmp(*argv,"-subject_hash") == 0)
			subject_hash= ++num;
#ifndef OPENSSL_NO_MD5
		else if (strcmp(*argv,"-subject_hash_old") == 0)
			subject_hash_old= ++num;
#endif
		else if (strcmp(*argv,"-issuer_hash") == 0)
			issuer_hash= ++num;
#ifndef OPENSSL_NO_MD5
		else if (strcmp(*argv,"-issuer_hash_old") == 0)
			issuer_hash_old= ++num;
#endif
		else if (strcmp(*argv,"-subject") == 0)
			subject= ++num;
		else if (strcmp(*argv,"-issuer") == 0)
			issuer= ++num;
		else if (strcmp(*argv,"-fingerprint") == 0)
			fingerprint= ++num;
		else if (strcmp(*argv,"-dates") == 0)
			{
			startdate= ++num;
			enddate= ++num;
			}
		else if (strcmp(*argv,"-purpose") == 0)
			pprint= ++num;
		else if (strcmp(*argv,"-startdate") == 0)
			startdate= ++num;
		else if (strcmp(*argv,"-enddate") == 0)
			enddate= ++num;
		else if (strcmp(*argv,"-checkend") == 0)
			{
			if (--argc < 1) goto bad;
			checkoffset=atoi(*(++argv));
			checkend=1;
			}
		else if (strcmp(*argv,"-noout") == 0)
			noout= ++num;
		else if (strcmp(*argv,"-trustout") == 0)
			trustout= 1;
		else if (strcmp(*argv,"-clrtrust") == 0)
			clrtrust= ++num;
		else if (strcmp(*argv,"-clrreject") == 0)
			clrreject= ++num;
		else if (strcmp(*argv,"-alias") == 0)
			aliasout= ++num;
		else if (strcmp(*argv,"-CAcreateserial") == 0)
			CA_createserial= ++num;
		else if (strcmp(*argv,"-clrext") == 0)
			clrext = 1;
#if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */
		else if (strcmp(*argv,"-crlext") == 0)
			{
			BIO_printf(bio_err,"use -clrext instead of -crlext\n");
			clrext = 1;
			}
#endif
		else if (strcmp(*argv,"-ocspid") == 0)
			ocspid= ++num;
		else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
			{
			/* ok */
			digest=md_alg;
			}
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		for (pp=x509_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err,"%s",*pp);
		goto end;
		}

#ifndef OPENSSL_NO_ENGINE
        e = setup_engine(bio_err, engine, 0);
#endif

	if (need_rand)
		app_RAND_load_file(NULL, bio_err, 0);

	ERR_load_crypto_strings();

	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
		{
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
		}

	if (!X509_STORE_set_default_paths(ctx))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM))
		{ CAkeyfile=CAfile; }
	else if ((CA_flag) && (CAkeyfile == NULL))
		{
		BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n");
		goto end;
		}

	if (extfile)
		{
		long errorline = -1;
		X509V3_CTX ctx2;
		extconf = NCONF_new(NULL);
		if (!NCONF_load(extconf, extfile,&errorline))
			{
			if (errorline <= 0)
				BIO_printf(bio_err,
					"error loading the config file '%s'\n",
								extfile);
                	else
                        	BIO_printf(bio_err,
				       "error on line %ld of config file '%s'\n"
							,errorline,extfile);
			goto end;
			}
		if (!extsect)
			{
			extsect = NCONF_get_string(extconf, "default", "extensions");
			if (!extsect)
				{
				ERR_clear_error();
				extsect = "default";
				}
			}
		X509V3_set_ctx_test(&ctx2);
		X509V3_set_nconf(&ctx2, extconf);
		if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL))
			{
			BIO_printf(bio_err,
				"Error Loading extension section %s\n",
								 extsect);
			ERR_print_errors(bio_err);
			goto end;
			}
		}


	if (reqfile)
		{
		EVP_PKEY *pkey;
		BIO *in;

		if (!sign_flag && !CA_flag)
			{
			BIO_printf(bio_err,"We need a private key to sign with\n");
			goto end;
			}
		in=BIO_new(BIO_s_file());
		if (in == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}

		if (infile == NULL)
			BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT);
		else
			{
			if (BIO_read_filename(in,infile) <= 0)
				{
				perror(infile);
				BIO_free(in);
				goto end;
				}
			}
		req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
		BIO_free(in);

		if (req == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}

		if (	(req->req_info == NULL) ||
			(req->req_info->pubkey == NULL) ||
			(req->req_info->pubkey->public_key == NULL) ||
			(req->req_info->pubkey->public_key->data == NULL))
			{
			BIO_printf(bio_err,"The certificate request appears to corrupted\n");
			BIO_printf(bio_err,"It does not contain a public key\n");
			goto end;
			}
		if ((pkey=X509_REQ_get_pubkey(req)) == NULL)
	                {
	                BIO_printf(bio_err,"error unpacking public key\n");
	                goto end;
	                }
		i=X509_REQ_verify(req,pkey);
		EVP_PKEY_free(pkey);
		if (i < 0)
			{
			BIO_printf(bio_err,"Signature verification error\n");
			ERR_print_errors(bio_err);
			goto end;
			}
	        if (i == 0)
			{
			BIO_printf(bio_err,"Signature did not match the certificate request\n");
			goto end;
			}
		else
			BIO_printf(bio_err,"Signature ok\n");

		print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag);

		if ((x=X509_new()) == NULL) goto end;

		if (sno == NULL)
			{
			sno = ASN1_INTEGER_new();
			if (!sno || !rand_serial(NULL, sno))
				goto end;
			if (!X509_set_serialNumber(x, sno)) 
				goto end;
			ASN1_INTEGER_free(sno);
			sno = NULL;
			}
		else if (!X509_set_serialNumber(x, sno)) 
			goto end;

		if (!X509_set_issuer_name(x,req->req_info->subject)) goto end;
		if (!X509_set_subject_name(x,req->req_info->subject)) goto end;

		X509_gmtime_adj(X509_get_notBefore(x),0);
	        X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL);

		pkey = X509_REQ_get_pubkey(req);
		X509_set_pubkey(x,pkey);
		EVP_PKEY_free(pkey);
		}
	else
		x=load_cert(bio_err,infile,informat,NULL,e,"Certificate");

	if (x == NULL) goto end;
	if (CA_flag)
		{
		xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate");
		if (xca == NULL) goto end;
		}

	if (!noout || text || next_serial)
		{
		OBJ_create("2.99999.3",
			"SET.ex3","SET x509v3 extension 3");

		out=BIO_new(BIO_s_file());
		if (out == NULL)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		if (outfile == NULL)
			{
			BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
			{
			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
			out = BIO_push(tmpbio, out);
			}
#endif
			}
		else
			{
			if (BIO_write_filename(out,outfile) <= 0)
				{
				perror(outfile);
				goto end;
				}
			}
		}

	if (alias) X509_alias_set1(x, (unsigned char *)alias, -1);

	if (clrtrust) X509_trust_clear(x);
	if (clrreject) X509_reject_clear(x);

	if (trust)
		{
		for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++)
			{
			objtmp = sk_ASN1_OBJECT_value(trust, i);
			X509_add1_trust_object(x, objtmp);
			}
		}

	if (reject)
		{
		for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++)
			{
			objtmp = sk_ASN1_OBJECT_value(reject, i);
			X509_add1_reject_object(x, objtmp);
			}
		}

	if (num)
		{
		for (i=1; i<=num; i++)
			{
			if (issuer == i)
				{
				print_name(STDout, "issuer= ",
					X509_get_issuer_name(x), nmflag);
				}
			else if (subject == i) 
				{
				print_name(STDout, "subject= ",
					X509_get_subject_name(x), nmflag);
				}
			else if (serial == i)
				{
				BIO_printf(STDout,"serial=");
				i2a_ASN1_INTEGER(STDout,
					X509_get_serialNumber(x));
				BIO_printf(STDout,"\n");
				}
			else if (next_serial == i)
				{
				BIGNUM *bnser;
				ASN1_INTEGER *ser;
				ser = X509_get_serialNumber(x);
				bnser = ASN1_INTEGER_to_BN(ser, NULL);
				if (!bnser)
					goto end;
				if (!BN_add_word(bnser, 1))
					goto end;
				ser = BN_to_ASN1_INTEGER(bnser, NULL);
				if (!ser)
					goto end;
				BN_free(bnser);
				i2a_ASN1_INTEGER(out, ser);
				ASN1_INTEGER_free(ser);
				BIO_puts(out, "\n");
				}
			else if ((email == i) || (ocsp_uri == i))
				{
				int j;
				STACK_OF(OPENSSL_STRING) *emlst;
				if (email == i)
					emlst = X509_get1_email(x);
				else
					emlst = X509_get1_ocsp(x);
				for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
					BIO_printf(STDout, "%s\n",
						   sk_OPENSSL_STRING_value(emlst, j));
				X509_email_free(emlst);
				}
			else if (aliasout == i)
				{
				unsigned char *alstr;
				alstr = X509_alias_get0(x, NULL);
				if (alstr) BIO_printf(STDout,"%s\n", alstr);
				else BIO_puts(STDout,"<No Alias>\n");
				}
			else if (subject_hash == i)
				{
				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
				}
#ifndef OPENSSL_NO_MD5
			else if (subject_hash_old == i)
				{
				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash_old(x));
				}
#endif
			else if (issuer_hash == i)
				{
				BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x));
				}
#ifndef OPENSSL_NO_MD5
			else if (issuer_hash_old == i)
				{
				BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash_old(x));
				}
#endif
			else if (pprint == i)
				{
				X509_PURPOSE *ptmp;
				int j;
				BIO_printf(STDout, "Certificate purposes:\n");
				for (j = 0; j < X509_PURPOSE_get_count(); j++)
					{
					ptmp = X509_PURPOSE_get0(j);
					purpose_print(STDout, x, ptmp);
					}
				}
			else
				if (modulus == i)
				{
				EVP_PKEY *pkey;

				pkey=X509_get_pubkey(x);
				if (pkey == NULL)
					{
					BIO_printf(bio_err,"Modulus=unavailable\n");
					ERR_print_errors(bio_err);
					goto end;
					}
				BIO_printf(STDout,"Modulus=");
#ifndef OPENSSL_NO_RSA
				if (pkey->type == EVP_PKEY_RSA)
					BN_print(STDout,pkey->pkey.rsa->n);
				else
#endif
#ifndef OPENSSL_NO_DSA
				if (pkey->type == EVP_PKEY_DSA)
					BN_print(STDout,pkey->pkey.dsa->pub_key);
				else
#endif
					BIO_printf(STDout,"Wrong Algorithm type");
				BIO_printf(STDout,"\n");
				EVP_PKEY_free(pkey);
				}
			else
				if (pubkey == i)
				{
				EVP_PKEY *pkey;

				pkey=X509_get_pubkey(x);
				if (pkey == NULL)
					{
					BIO_printf(bio_err,"Error getting public key\n");
					ERR_print_errors(bio_err);
					goto end;
					}
				PEM_write_bio_PUBKEY(STDout, pkey);
				EVP_PKEY_free(pkey);
				}
			else
				if (C == i)
				{
				unsigned char *d;
				char *m;
				int y,z;

				X509_NAME_oneline(X509_get_subject_name(x),
					buf,sizeof buf);
				BIO_printf(STDout,"/* subject:%s */\n",buf);
				m=X509_NAME_oneline(
					X509_get_issuer_name(x),buf,
					sizeof buf);
				BIO_printf(STDout,"/* issuer :%s */\n",buf);

				z=i2d_X509(x,NULL);
				m=OPENSSL_malloc(z);

				d=(unsigned char *)m;
				z=i2d_X509_NAME(X509_get_subject_name(x),&d);
				BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z);
				d=(unsigned char *)m;
				for (y=0; y<z; y++)
					{
					BIO_printf(STDout,"0x%02X,",d[y]);
					if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n");
					}
				if (y%16 != 0) BIO_printf(STDout,"\n");
				BIO_printf(STDout,"};\n");

				z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d);
				BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z);
				d=(unsigned char *)m;
				for (y=0; y<z; y++)
					{
					BIO_printf(STDout,"0x%02X,",d[y]);
					if ((y & 0x0f) == 0x0f)
						BIO_printf(STDout,"\n");
					}
				if (y%16 != 0) BIO_printf(STDout,"\n");
				BIO_printf(STDout,"};\n");

				z=i2d_X509(x,&d);
				BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z);
				d=(unsigned char *)m;
				for (y=0; y<z; y++)
					{
					BIO_printf(STDout,"0x%02X,",d[y]);
					if ((y & 0x0f) == 0x0f)
						BIO_printf(STDout,"\n");
					}
				if (y%16 != 0) BIO_printf(STDout,"\n");
				BIO_printf(STDout,"};\n");

				OPENSSL_free(m);
				}
			else if (text == i)
				{
				X509_print_ex(out,x,nmflag, certflag);
				}
			else if (startdate == i)
				{
				BIO_puts(STDout,"notBefore=");
				ASN1_TIME_print(STDout,X509_get_notBefore(x));
				BIO_puts(STDout,"\n");
				}
			else if (enddate == i)
				{
				BIO_puts(STDout,"notAfter=");
				ASN1_TIME_print(STDout,X509_get_notAfter(x));
				BIO_puts(STDout,"\n");
				}
			else if (fingerprint == i)
				{
				int j;
				unsigned int n;
				unsigned char md[EVP_MAX_MD_SIZE];
				const EVP_MD *fdig = digest;

				if (!fdig)
					fdig = EVP_sha1();

				if (!X509_digest(x,fdig,md,&n))
					{
					BIO_printf(bio_err,"out of memory\n");
					goto end;
					}
				BIO_printf(STDout,"%s Fingerprint=",
						OBJ_nid2sn(EVP_MD_type(fdig)));
				for (j=0; j<(int)n; j++)
					{
					BIO_printf(STDout,"%02X%c",md[j],
						(j+1 == (int)n)
						?'\n':':');
					}
				}

			/* should be in the library */
			else if ((sign_flag == i) && (x509req == 0))
				{
				BIO_printf(bio_err,"Getting Private key\n");
				if (Upkey == NULL)
					{
					Upkey=load_key(bio_err,
						keyfile, keyformat, 0,
						passin, e, "Private key");
					if (Upkey == NULL) goto end;
					}

				assert(need_rand);
				if (!sign(x,Upkey,days,clrext,digest,
						 extconf, extsect)) goto end;
				}
			else if (CA_flag == i)
				{
				BIO_printf(bio_err,"Getting CA Private Key\n");
				if (CAkeyfile != NULL)
					{
					CApkey=load_key(bio_err,
						CAkeyfile, CAkeyformat,
						0, passin, e,
						"CA Private Key");
					if (CApkey == NULL) goto end;
					}
				
				assert(need_rand);
				if (!x509_certify(ctx,CAfile,digest,x,xca,
					CApkey, sigopts,
					CAserial,CA_createserial,days, clrext,
					extconf, extsect, sno))
					goto end;
				}
			else if (x509req == i)
				{
				EVP_PKEY *pk;

				BIO_printf(bio_err,"Getting request Private Key\n");
				if (keyfile == NULL)
					{
					BIO_printf(bio_err,"no request key file specified\n");
					goto end;
					}
				else
					{
					pk=load_key(bio_err,
						keyfile, keyformat, 0,
						passin, e, "request key");
					if (pk == NULL) goto end;
					}

				BIO_printf(bio_err,"Generating certificate request\n");

				rq=X509_to_X509_REQ(x,pk,digest);
				EVP_PKEY_free(pk);
				if (rq == NULL)
					{
					ERR_print_errors(bio_err);
					goto end;
					}
				if (!noout)
					{
					X509_REQ_print(out,rq);
					PEM_write_bio_X509_REQ(out,rq);
					}
				noout=1;
				}
			else if (ocspid == i)
				{
				X509_ocspid_print(out, x);
				}
			}
		}

	if (checkend)
		{
		time_t tcheck=time(NULL) + checkoffset;

		if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0)
			{
			BIO_printf(out,"Certificate will expire\n");
			ret=1;
			}
		else
			{
			BIO_printf(out,"Certificate will not expire\n");
			ret=0;
			}
		goto end;
		}

	if (noout)
		{
		ret=0;
		goto end;
		}

	if 	(outformat == FORMAT_ASN1)
		i=i2d_X509_bio(out,x);
	else if (outformat == FORMAT_PEM)
		{
		if (trustout) i=PEM_write_bio_X509_AUX(out,x);
		else i=PEM_write_bio_X509(out,x);
		}
	else if (outformat == FORMAT_NETSCAPE)
		{
		NETSCAPE_X509 nx;
		ASN1_OCTET_STRING hdr;

		hdr.data=(unsigned char *)NETSCAPE_CERT_HDR;
		hdr.length=strlen(NETSCAPE_CERT_HDR);
		nx.header= &hdr;
		nx.cert=x;

		i=ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509),out,&nx);
		}
	else	{
		BIO_printf(bio_err,"bad output format specified for outfile\n");
		goto end;
		}
	if (!i)
		{
		BIO_printf(bio_err,"unable to write certificate\n");
		ERR_print_errors(bio_err);
		goto end;
		}
	ret=0;
end:
	if (need_rand)
		app_RAND_write_file(NULL, bio_err);
	OBJ_cleanup();
	NCONF_free(extconf);
	BIO_free_all(out);
	BIO_free_all(STDout);
	X509_STORE_free(ctx);
	X509_REQ_free(req);
	X509_free(x);
	X509_free(xca);
	EVP_PKEY_free(Upkey);
	EVP_PKEY_free(CApkey);
	if (sigopts)
		sk_OPENSSL_STRING_free(sigopts);
	X509_REQ_free(rq);
	ASN1_INTEGER_free(sno);
	sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
	sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
	if (passin) OPENSSL_free(passin);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Example #25
0
static int ssl_hook_pre_config(apr_pool_t *pconf,
                               apr_pool_t *plog,
                               apr_pool_t *ptemp)
{
    modssl_running_statically = modssl_is_prelinked();

    /* Some OpenSSL internals are allocated per-thread, make sure they
     * are associated to the/our same thread-id until cleaned up.
     */
#if APR_HAS_THREADS && OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
    ssl_util_thread_id_setup(pconf);
#endif

    /* We must register the library in full, to ensure our configuration
     * code can successfully test the SSL environment.
     */
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
    CRYPTO_malloc_init();
#else
    OPENSSL_malloc_init();
#endif
    ERR_load_crypto_strings();
    SSL_load_error_strings();
    SSL_library_init();
#if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
    ENGINE_load_builtin_engines();
#endif
    OpenSSL_add_all_algorithms();
    OPENSSL_load_builtin_modules();

    if (OBJ_txt2nid("id-on-dnsSRV") == NID_undef) {
        (void)OBJ_create("1.3.6.1.5.5.7.8.7", "id-on-dnsSRV",
                         "SRVName otherName form");
    }

    /* Start w/o errors (e.g. OBJ_txt2nid() above) */
    ERR_clear_error();

    /*
     * Let us cleanup the ssl library when the module is unloaded
     */
    apr_pool_cleanup_register(pconf, NULL, ssl_cleanup_pre_config,
                                           apr_pool_cleanup_null);

    /* Register us to handle mod_log_config %c/%x variables */
    ssl_var_log_config_register(pconf);

    /* Register to handle mod_status status page generation */
    ssl_scache_status_register(pconf);

    /* Register mutex type names so they can be configured with Mutex */
    ap_mutex_register(pconf, SSL_CACHE_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
#ifdef HAVE_OCSP_STAPLING
    ap_mutex_register(pconf, SSL_STAPLING_CACHE_MUTEX_TYPE, NULL,
                      APR_LOCK_DEFAULT, 0);
    ap_mutex_register(pconf, SSL_STAPLING_REFRESH_MUTEX_TYPE, NULL,
                      APR_LOCK_DEFAULT, 0);
#endif

    return OK;
}