static void print_conf(CONF_VALUE *cv)
	{
	int i;
	CONF_VALUE *v;
	char *section;
	char *name;
	char *value;
	STACK *s;

	/* If it is a single entry, return */

	if (cv->name != NULL) return;

	TINYCLR_SSL_PRINTF("[ %s ]\n",cv->section);
	s=(STACK *)cv->value;

	for (i=0; i<sk_num(s); i++)
		{
		v=(CONF_VALUE *)sk_value(s,i);
		section=(v->section == NULL)?"None":v->section;
		name=(v->name == NULL)?"None":v->name;
		value=(v->value == NULL)?"None":v->value;
		TINYCLR_SSL_PRINTF("%s=%s\n",name,value);
		}
	TINYCLR_SSL_PRINTF("\n");
	}
/*
 * call-seq:
 *    ctx.ciphers => [[name, version, bits, alg_bits], ...]
 */
static VALUE
ossl_sslctx_get_ciphers(VALUE self)
{
    SSL_CTX *ctx;
    STACK_OF(SSL_CIPHER) *ciphers;
    SSL_CIPHER *cipher;
    VALUE ary;
    int i, num;

    Data_Get_Struct(self, SSL_CTX, ctx);
    if(!ctx){
        rb_warning("SSL_CTX is not initialized.");
        return Qnil;
    }
    ciphers = ctx->cipher_list;

    if (!ciphers)
        return rb_ary_new();

    num = sk_num((STACK*)ciphers);
    ary = rb_ary_new2(num);
    for(i = 0; i < num; i++){
        cipher = (SSL_CIPHER*)sk_value((STACK*)ciphers, i);
        rb_ary_push(ary, ossl_ssl_cipher_to_ary(cipher));
    }
    return ary;
}
Exemplo n.º 3
0
void TXT_DB_free(TXT_DB *db)
	{
	int i,n;
	char **p,*max;

	if(db == NULL)
	    return;

	if (db->index != NULL)
		{
		for (i=db->num_fields-1; i>=0; i--)
			if (db->index[i] != NULL) lh_free(db->index[i]);
		OPENSSL_free(db->index);
		}
	if (db->qual != NULL)
		OPENSSL_free(db->qual);
	if (db->data != NULL)
		{
		for (i=sk_num(db->data)-1; i>=0; i--)
			{
			/* check if any 'fields' have been allocated
			 * from outside of the initial block */
			p=(char **)sk_value(db->data,i);
			max=p[db->num_fields]; /* last address */
			if (max == NULL) /* new row */
				{
				for (n=0; n<db->num_fields; n++)
					if (p[n] != NULL) OPENSSL_free(p[n]);
				}
			else
				{
				for (n=0; n<db->num_fields; n++)
					{
					if (((p[n] < (char *)p) || (p[n] > max))
						&& (p[n] != NULL))
						OPENSSL_free(p[n]);
					}
				}
			OPENSSL_free(sk_value(db->data,i));
			}
		sk_free(db->data);
		}
	OPENSSL_free(db);
	}
Exemplo n.º 4
0
const char *CRYPTO_get_lock_name(int type)
	{
	if (type < 0)
		return("dynamic");
	else if (type < CRYPTO_NUM_LOCKS)
		return(lock_names[type]);
	else if (type-CRYPTO_NUM_LOCKS > sk_num(app_locks))
		return("ERROR");
	else
		return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS));
	}
Exemplo n.º 5
0
long TXT_DB_write(BIO *out, TXT_DB *db)
	{
	long i,j,n,nn,l,tot=0;
	char *p,**pp,*f;
	BUF_MEM *buf=NULL;
	long ret= -1;

	if ((buf=BUF_MEM_new()) == NULL)
		goto err;
	n=sk_num(db->data);
	nn=db->num_fields;
	for (i=0; i<n; i++)
		{
		pp=(char **)sk_value(db->data,i);

		l=0;
		for (j=0; j<nn; j++)
			{
			if (pp[j] != NULL)
				l+=strlen(pp[j]);
			}
		if (!BUF_MEM_grow_clean(buf,(int)(l*2+nn))) goto err;

		p=buf->data;
		for (j=0; j<nn; j++)
			{
			f=pp[j];
			if (f != NULL)
				for (;;) 
					{
					if (*f == '\0') break;
					if (*f == '\t') *(p++)='\\';
					*(p++)= *(f++);
					}
			*(p++)='\t';
			}
		p[-1]='\n';
		j=p-buf->data;
		if (BIO_write(out,buf->data,(int)j) != j)
			goto err;
		tot+=j;
		}
	ret=tot;
err:
	if (buf != NULL) BUF_MEM_free(buf);
	return(ret);
	}
Exemplo n.º 6
0
static void util_do_cmds(ENGINE *e, STACK *cmds, BIO *bio_out, const char *indent)
	{
	int loop, res, num = sk_num(cmds);
	if(num < 0)
		{
		BIO_printf(bio_out, "[Error]: internal stack error\n");
		return;
		}
	for(loop = 0; loop < num; loop++)
		{
		char buf[256];
		const char *cmd, *arg;
		cmd = sk_value(cmds, loop);
		res = 1; /* assume success */
		/* Check if this command has no ":arg" */
		if((arg = strstr(cmd, ":")) == NULL)
			{
			if(!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0))
				res = 0;
			}
		else
			{
			if((int)(arg - cmd) > 254)
				{
				BIO_printf(bio_out,"[Error]: command name too long\n");
				return;
				}
			memcpy(buf, cmd, (int)(arg - cmd));
			buf[arg-cmd] = '\0';
			arg++; /* Move past the ":" */
			/* Call the command with the argument */
			if(!ENGINE_ctrl_cmd_string(e, buf, arg, 0))
				res = 0;
			}
		if(res)
			BIO_printf(bio_out, "[Success]: %s\n", cmd);
		else
			{
			BIO_printf(bio_out, "[Failure]: %s\n", cmd);
			ERR_print_errors(bio_out);
			}
		}
	}
Exemplo n.º 7
0
int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(char **),
		LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
	{
	LHASH *idx;
	char **r;
	int i,n;

	if (field >= db->num_fields)
		{
		db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
		return(0);
		}
	if ((idx=lh_new(hash,cmp)) == NULL)
		{
		db->error=DB_ERROR_MALLOC;
		return(0);
		}
	n=sk_num(db->data);
	for (i=0; i<n; i++)
		{
		r=(char **)sk_value(db->data,i);
		if ((qual != NULL) && (qual(r) == 0)) continue;
		if ((r=lh_insert(idx,r)) != NULL)
			{
			db->error=DB_ERROR_INDEX_CLASH;
			db->arg1=sk_find(db->data,(char *)r);
			db->arg2=i;
			lh_free(idx);
			return(0);
			}
		}
	if (db->index[field] != NULL) lh_free(db->index[field]);
	db->index[field]=idx;
	db->qual[field]=qual;
	return(1);
	}
Exemplo n.º 8
0
carray * mailstream_low_ssl_get_certificate_chain(mailstream_low * s)
{
#ifdef USE_SSL
#ifndef USE_GNUTLS
  STACK_OF(X509) * skx;
  struct mailstream_ssl_data * ssl_data;
  carray * result;
  int skpos;
  
  ssl_data = (struct mailstream_ssl_data *) s->data;
  if (!(skx = SSL_get_peer_cert_chain(ssl_data->ssl_conn))) {
    return NULL;
  }
  
  result = carray_new(4);
  for(skpos = 0 ; skpos < sk_num(skx) ; skpos ++) {
    X509 * x = (X509 *) sk_value(skx, skpos);
    unsigned char * p;
    MMAPString * str;
    int length = i2d_X509(x, NULL);
    str = mmap_string_sized_new(length);
    p = (unsigned char *) str->str;
    str->len = length;
    i2d_X509(x, &p);
    carray_add(result, str, NULL);
  }
  
  return result;
#else
  /* TODO: GnuTLS implementation */
  return NULL;
#endif
#else
  return NULL;
#endif
}
Exemplo n.º 9
0
carray * mailstream_low_ssl_get_certificate_chain(mailstream_low * s)
{
#ifdef USE_SSL
  struct mailstream_ssl_data * ssl_data;
  carray * result;
  int skpos;
#ifndef USE_GNUTLS
  STACK_OF(X509) * skx;
  
  ssl_data = (struct mailstream_ssl_data *) s->data;
  if (!(skx = SSL_get_peer_cert_chain(ssl_data->ssl_conn))) {
    return NULL;
  }
  
  result = carray_new(4);
  for(skpos = 0 ; skpos < sk_num((_STACK *) skx) ; skpos ++) {
    X509 * x = (X509 *) sk_value((_STACK *) skx, skpos);
    unsigned char * p;
    MMAPString * str;
    int length = i2d_X509(x, NULL);
    str = mmap_string_sized_new(length);
    p = (unsigned char *) str->str;
    str->len = length;
    i2d_X509(x, &p);
    carray_add(result, str, NULL);
  }
  
  return result;
#else
  gnutls_session session = NULL;
  const gnutls_datum *raw_cert_list;
  unsigned int raw_cert_list_length;

  ssl_data = (struct mailstream_ssl_data *) s->data;

  session = ssl_data->session;
  raw_cert_list = gnutls_certificate_get_peers(session, &raw_cert_list_length);

  if (raw_cert_list && gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) {
    result = carray_new(4);
    for(skpos = 0 ; skpos < raw_cert_list_length ; skpos ++) {
      gnutls_x509_crt cert = NULL;
      if (gnutls_x509_crt_init(&cert) >= 0
       && gnutls_x509_crt_import(cert, &raw_cert_list[skpos], GNUTLS_X509_FMT_DER) >= 0) {
         size_t cert_size = 0;
         MMAPString * str = NULL;
         unsigned char * p;

         if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, NULL, &cert_size)
	     == GNUTLS_E_SHORT_MEMORY_BUFFER) {
           str = mmap_string_sized_new(cert_size);
           p = (unsigned char *) str->str;
           str->len = cert_size;
	 }
	 if (str != NULL &&
             gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, p, &cert_size) >= 0) {
           carray_add(result, str, NULL);
	 } else {
	   return NULL;
	 }
         gnutls_x509_crt_deinit(cert);
       }
    }
  }

  return result;

  return NULL;
#endif
#else
  return NULL;
#endif
}
Exemplo n.º 10
0
/* int is_set:  if TRUE, then sort the contents (i.e. it isn't a SEQUENCE)    */
int i2d_ASN1_SET(STACK *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
		 int ex_class, int is_set)
	{
	int ret=0,r;
	int i;
	unsigned char *p;
        unsigned char *pStart, *pTempMem;
        MYBLOB *rgSetBlob;
        int totSize;

	if (a == NULL) return(0);
	for (i=sk_num(a)-1; i>=0; i--)
		ret+=i2d(sk_value(a,i),NULL);
	r=ASN1_object_size(1,ret,ex_tag);
	if (pp == NULL) return(r);

	p= *pp;
	ASN1_put_object(&p,1,ret,ex_tag,ex_class);

/* Modified by [email protected] */
	/* And then again by Ben */
	/* And again by Steve */

	if(!is_set || (sk_num(a) < 2))
		{
		for (i=0; i<sk_num(a); i++)
                	i2d(sk_value(a,i),&p);

		*pp=p;
		return(r);
		}

        pStart  = p; /* Catch the beg of Setblobs*/
		/* In this array we will store the SET blobs */
		rgSetBlob = (MYBLOB *)OPENSSL_malloc(sk_num(a) * sizeof(MYBLOB));
		if (rgSetBlob == NULL)
			{
			ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
			return(0);
			}

        for (i=0; i<sk_num(a); i++)
	        {
                rgSetBlob[i].pbData = p;  /* catch each set encode blob */
                i2d(sk_value(a,i),&p);
                rgSetBlob[i].cbData = (int)(p - rgSetBlob[i].pbData); /* Length of this
SetBlob
*/
		}
        *pp=p;
        totSize = (int)(p - pStart); /* This is the total size of all set blobs */

 /* Now we have to sort the blobs. I am using a simple algo.
    *Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/
        qsort( rgSetBlob, sk_num(a), sizeof(MYBLOB), SetBlobCmp);
		if (!(pTempMem = OPENSSL_malloc(totSize)))
			{
			ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
			return(0);
			}

/* Copy to temp mem */
        p = pTempMem;
        for(i=0; i<sk_num(a); ++i)
		{
                memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
                p += rgSetBlob[i].cbData;
		}

/* Copy back to user mem*/
        memcpy(pStart, pTempMem, totSize);
        OPENSSL_free(pTempMem);
        OPENSSL_free(rgSetBlob);

        return(r);
        }
Exemplo n.º 11
0
static ngx_int_t
ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder)
{
    ngx_url_t                  u;
    char                      *s;
    ngx_ssl_stapling_t        *staple;
    STACK_OF(OPENSSL_STRING)  *aia;

    staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);

    if (responder->len == 0) {

        /* extract OCSP responder URL from certificate */

        aia = X509_get1_ocsp(staple->cert);
        if (aia == NULL) {
            ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
                          "\"ssl_stapling\" ignored, "
                          "no OCSP responder URL in the certificate");
            return NGX_DECLINED;
        }

#if OPENSSL_VERSION_NUMBER >= 0x10000000L
        s = sk_OPENSSL_STRING_value(aia, 0);
#else
        s = sk_value(aia, 0);
#endif
        if (s == NULL) {
            ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
                          "\"ssl_stapling\" ignored, "
                          "no OCSP responder URL in the certificate");
            X509_email_free(aia);
            return NGX_DECLINED;
        }

        responder->len = ngx_strlen(s);
        responder->data = ngx_palloc(cf->pool, responder->len);
        if (responder->data == NULL) {
            X509_email_free(aia);
            return NGX_ERROR;
        }

        ngx_memcpy(responder->data, s, responder->len);
        X509_email_free(aia);
    }

    ngx_memzero(&u, sizeof(ngx_url_t));

    u.url = *responder;
    u.default_port = 80;
    u.uri_part = 1;

    if (u.url.len > 7
        && ngx_strncasecmp(u.url.data, (u_char *) "http://", 7) == 0)
    {
        u.url.len -= 7;
        u.url.data += 7;

    } else {
        ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
                      "\"ssl_stapling\" ignored, "
                      "invalid URL prefix in OCSP responder \"%V\"", &u.url);
        return NGX_DECLINED;
    }

    if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
        if (u.err) {
            ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
                          "\"ssl_stapling\" ignored, "
                          "%s in OCSP responder \"%V\"", u.err, &u.url);
            return NGX_DECLINED;
        }

        return NGX_ERROR;
    }

    staple->addrs = u.addrs;
    staple->host = u.host;
    staple->uri = u.uri;
    staple->port = u.port;

    if (staple->uri.len == 0) {
        ngx_str_set(&staple->uri, "/");
    }

    return NGX_OK;
}
Exemplo n.º 12
0
int SslOcspStapling::getResponder(X509 *pCert)
{
    char                    *pUrl;
    X509                    *pCAt;
    STACK_OF(X509)          *pXchain;
    int                     i;
    int                     n;

#if OPENSSL_VERSION_NUMBER >= 0x10000003L
    STACK_OF(OPENSSL_STRING)  *strResp;
#else
    STACK                    *strResp;
#endif
    if (m_sOcspResponder.c_str())
        return 0;
    strResp = X509_get1_ocsp(pCert);
    if (strResp == NULL)
    {
        pXchain = m_pCtx->extra_certs;
        n = sk_X509_num(pXchain);
        for (i = 0; i < n; i++)
        {
            pCert = sk_X509_value(pXchain, i);
            strResp = X509_get1_ocsp(pCert);
            if (strResp)
                break;
        }
    }
    if (strResp == NULL)
    {
        if (m_sCAfile.c_str() == NULL)
            return LS_FAIL;
        pCAt = load_cert(m_sCAfile.c_str());
        if (pCAt == NULL)
        {
            setLastErrMsg("Failed to load file: %s!\n", m_sCAfile.c_str());
            return LS_FAIL;
        }

        strResp = X509_get1_ocsp(pCAt);
        X509_free(pCAt);
        if (strResp == NULL)
        {
            setLastErrMsg("Failed to get responder!\n");
            return LS_FAIL;
        }
    }
#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
    pUrl = sk_OPENSSL_STRING_value(strResp, 0);
#elif OPENSSL_VERSION_NUMBER >= 0x10000003L
    pUrl = (char *)sk_value((const _STACK *) strResp, 0);
#else
    pUrl = (char *)sk_value((const STACK *) strResp, 0);
#endif
    if (pUrl)
    {
        m_sOcspResponder.setStr(pUrl);
        return 0;
    }
    X509_email_free(strResp);
    setLastErrMsg("Failed to get responder Url!\n");
    return LS_FAIL;
}
Exemplo n.º 13
0
int MAIN(int argc, char **argv)
	{
	int ret=1,i;
	const char **pp;
	int verbose=0, list_cap=0, test_avail=0, test_avail_noise = 0;
	ENGINE *e;
	STACK *engines = sk_new_null();
	STACK *pre_cmds = sk_new_null();
	STACK *post_cmds = sk_new_null();
	int badops=1;
	BIO *bio_out=NULL;
	const char *indent = "     ";

	apps_startup();
	SSL_load_error_strings();

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

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

	argc--;
	argv++;
	while (argc >= 1)
		{
		if (strncmp(*argv,"-v",2) == 0)
			{
			if(strspn(*argv + 1, "v") < strlen(*argv + 1))
				goto skip_arg_loop;
			if((verbose=strlen(*argv + 1)) > 4)
				goto skip_arg_loop;
			}
		else if (strcmp(*argv,"-c") == 0)
			list_cap=1;
		else if (strncmp(*argv,"-t",2) == 0)
			{
			test_avail=1;
			if(strspn(*argv + 1, "t") < strlen(*argv + 1))
				goto skip_arg_loop;
			if((test_avail_noise = strlen(*argv + 1) - 1) > 1)
				goto skip_arg_loop;
			}
		else if (strcmp(*argv,"-pre") == 0)
			{
			argc--; argv++;
			if (argc == 0)
				goto skip_arg_loop;
			sk_push(pre_cmds,*argv);
			}
		else if (strcmp(*argv,"-post") == 0)
			{
			argc--; argv++;
			if (argc == 0)
				goto skip_arg_loop;
			sk_push(post_cmds,*argv);
			}
		else if ((strncmp(*argv,"-h",2) == 0) ||
				(strcmp(*argv,"-?") == 0))
			goto skip_arg_loop;
		else
			sk_push(engines,*argv);
		argc--;
		argv++;
		}
	/* Looks like everything went OK */
	badops = 0;
skip_arg_loop:

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

	if (sk_num(engines) == 0)
		{
		for(e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e))
			{
			sk_push(engines,(char *)ENGINE_get_id(e));
			}
		}

	for (i=0; i<sk_num(engines); i++)
		{
		const char *id = sk_value(engines,i);
		if ((e = ENGINE_by_id(id)) != NULL)
			{
			const char *name = ENGINE_get_name(e);
			/* Do "id" first, then "name". Easier to auto-parse. */
			BIO_printf(bio_out, "(%s) %s\n", id, name);
			util_do_cmds(e, pre_cmds, bio_out, indent);
			if (strcmp(ENGINE_get_id(e), id) != 0)
				{
				BIO_printf(bio_out, "Loaded: (%s) %s\n",
					ENGINE_get_id(e), ENGINE_get_name(e));
				}
			if (list_cap)
				{
				int cap_size = 256;
				char *cap_buf = NULL;
				int k,n;
				const int *nids;
				ENGINE_CIPHERS_PTR fn_c;
				ENGINE_DIGESTS_PTR fn_d;

				if (ENGINE_get_RSA(e) != NULL
					&& !append_buf(&cap_buf, "RSA",
						&cap_size, 256))
					goto end;
				if (ENGINE_get_DSA(e) != NULL
					&& !append_buf(&cap_buf, "DSA",
						&cap_size, 256))
					goto end;
				if (ENGINE_get_DH(e) != NULL
					&& !append_buf(&cap_buf, "DH",
						&cap_size, 256))
					goto end;
				if (ENGINE_get_RAND(e) != NULL
					&& !append_buf(&cap_buf, "RAND",
						&cap_size, 256))
					goto end;

				fn_c = ENGINE_get_ciphers(e);
				if(!fn_c) goto skip_ciphers;
				n = fn_c(e, NULL, &nids, 0);
				for(k=0 ; k < n ; ++k)
					if(!append_buf(&cap_buf,
						       OBJ_nid2sn(nids[k]),
						       &cap_size, 256))
						goto end;

skip_ciphers:
				fn_d = ENGINE_get_digests(e);
				if(!fn_d) goto skip_digests;
				n = fn_d(e, NULL, &nids, 0);
				for(k=0 ; k < n ; ++k)
					if(!append_buf(&cap_buf,
						       OBJ_nid2sn(nids[k]),
						       &cap_size, 256))
						goto end;

skip_digests:
				if (cap_buf && (*cap_buf != '\0'))
					BIO_printf(bio_out, " [%s]\n", cap_buf);

				OPENSSL_free(cap_buf);
				}
			if(test_avail)
				{
				BIO_printf(bio_out, "%s", indent);
				if (ENGINE_init(e))
					{
					BIO_printf(bio_out, "[ available ]\n");
					util_do_cmds(e, post_cmds, bio_out, indent);
					ENGINE_finish(e);
					}
				else
					{
					BIO_printf(bio_out, "[ unavailable ]\n");
					if(test_avail_noise)
						ERR_print_errors_fp(stdout);
					ERR_clear_error();
					}
				}
			if((verbose > 0) && !util_verbose(e, verbose, bio_out, indent))
				goto end;
			ENGINE_free(e);
			}
		else
			ERR_print_errors(bio_err);
		}

	ret=0;
end:

	ERR_print_errors(bio_err);
	sk_pop_free(engines, identity);
	sk_pop_free(pre_cmds, identity);
	sk_pop_free(post_cmds, identity);
	if (bio_out != NULL) BIO_free_all(bio_out);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Exemplo n.º 14
0
int MAIN(int argc, char **argv)
	{
	int i,badops=0;
	BIO *in=NULL,*out=NULL;
	int informat,outformat;
	char *infile,*outfile,*prog,*certfile;
	PKCS7 *p7 = NULL;
	PKCS7_SIGNED *p7s = NULL;
	X509_CRL *crl=NULL;
	STACK *certflst=NULL;
	STACK_OF(X509_CRL) *crl_stack=NULL;
	STACK_OF(X509) *cert_stack=NULL;
	int ret=1,nocrl=0;

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	infile=NULL;
	outfile=NULL;
	informat=FORMAT_PEM;
	outformat=FORMAT_PEM;

	prog=argv[0];
	argc--;
	argv++;
	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,"-in") == 0)
			{
			if (--argc < 1) goto bad;
			infile= *(++argv);
			}
		else if (strcmp(*argv,"-nocrl") == 0)
			{
			nocrl=1;
			}
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
		else if (strcmp(*argv,"-certfile") == 0)
			{
			if (--argc < 1) goto bad;
			if(!certflst) certflst = sk_new_null();
			sk_push(certflst,*(++argv));
			}
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
		BIO_printf(bio_err,"where options are\n");
		BIO_printf(bio_err," -inform arg    input format - DER or PEM\n");
		BIO_printf(bio_err," -outform arg   output format - DER or PEM\n");
		BIO_printf(bio_err," -in arg        input file\n");
		BIO_printf(bio_err," -out arg       output file\n");
		BIO_printf(bio_err," -certfile arg  certificates file of chain to a trusted CA\n");
		BIO_printf(bio_err,"                (can be used more than once)\n");
		BIO_printf(bio_err," -nocrl         no crl to load, just certs from '-certfile'\n");
		EXIT(1);
		}

	ERR_load_crypto_strings();

	in=BIO_new(BIO_s_file());
	out=BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if (!nocrl)
		{
		if (infile == NULL)
			BIO_set_fp(in,stdin,BIO_NOCLOSE);
		else
			{
			if (BIO_read_filename(in,infile) <= 0)
				{
				perror(infile);
				goto end;
				}
			}

		if 	(informat == FORMAT_ASN1)
			crl=d2i_X509_CRL_bio(in,NULL);
		else if (informat == FORMAT_PEM)
			crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
		else	{
			BIO_printf(bio_err,"bad input format specified for input crl\n");
			goto end;
			}
		if (crl == NULL)
			{
			BIO_printf(bio_err,"unable to load CRL\n");
			ERR_print_errors(bio_err);
			goto end;
			}
		}
	
	if ((p7=PKCS7_new()) == NULL) goto end;
	if ((p7s=PKCS7_SIGNED_new()) == NULL) goto end;
	p7->type=OBJ_nid2obj(NID_pkcs7_signed);
	p7->d.sign=p7s;
	p7s->contents->type=OBJ_nid2obj(NID_pkcs7_data);

	if (!ASN1_INTEGER_set(p7s->version,1)) goto end;
	if ((crl_stack=sk_X509_CRL_new_null()) == NULL) goto end;
	p7s->crl=crl_stack;
	if (crl != NULL)
		{
		sk_X509_CRL_push(crl_stack,crl);
		crl=NULL; /* now part of p7 for OPENSSL_freeing */
		}

	if ((cert_stack=sk_X509_new_null()) == NULL) goto end;
	p7s->cert=cert_stack;

	if(certflst) for(i = 0; i < sk_num(certflst); i++) {
		certfile = sk_value(certflst, i);
		if (add_certs_from_file(cert_stack,certfile) < 0)
			{
			BIO_printf(bio_err, "error loading certificates\n");
			ERR_print_errors(bio_err);
			goto end;
			}
	}

	sk_free(certflst);

	if (outfile == NULL)
		{
		BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef 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 	(outformat == FORMAT_ASN1)
		i=i2d_PKCS7_bio(out,p7);
	else if (outformat == FORMAT_PEM)
		i=PEM_write_bio_PKCS7(out,p7);
	else	{
		BIO_printf(bio_err,"bad output format specified for outfile\n");
		goto end;
		}
	if (!i)
		{
		BIO_printf(bio_err,"unable to write pkcs7 object\n");
		ERR_print_errors(bio_err);
		goto end;
		}
	ret=0;
end:
	if (in != NULL) BIO_free(in);
	if (out != NULL) BIO_free_all(out);
	if (p7 != NULL) PKCS7_free(p7);
	if (crl != NULL) X509_CRL_free(crl);

	EXIT(ret);
	}
Exemplo n.º 15
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;
	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,hash=0,subject=0,issuer=0,startdate=0,enddate=0;
	int ocspid=0;
	int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=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;
	char **pp;
	X509_STORE *ctx=NULL;
	X509_REQ *rq=NULL;
	int fingerprint=0;
	char buf[256];
	const EVP_MD *md_alg,*digest=EVP_md5();
	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;
	char *engine=NULL;

	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_func(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,"-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;
			}
		else if (strcmp(*argv,"-setalias") == 0)
			{
			if (--argc < 1) goto bad;
			alias= *(++argv);
			trustout = 1;
			}
		else if (strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine= *(++argv);
			}
		else if (strcmp(*argv,"-C") == 0)
			C= ++num;
		else if (strcmp(*argv,"-email") == 0)
			email= ++num;
		else if (strcmp(*argv,"-serial") == 0)
			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)
			hash= ++num;
		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;
		}

        e = setup_engine(bio_err, engine, 0);

	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;
		X509_CINF *ci;
		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;
		ci=x->cert_info;

		if (sno)
			{
			if (!X509_set_serialNumber(x, sno))
				goto end;
			}
		else if (!ASN1_INTEGER_set(X509_get_serialNumber(x),0)) 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_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);

		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)
		{
		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,x->cert_info->serialNumber);
				BIO_printf(STDout,"\n");
				}
			else if (email == i) 
				{
				int j;
				STACK *emlst;
				emlst = X509_get1_email(x);
				for (j = 0; j < sk_num(emlst); j++)
					BIO_printf(STDout, "%s\n", sk_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 (hash == i)
				{
				BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
				}
			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];

				if (!X509_digest(x,digest,md,&n))
					{
					BIO_printf(bio_err,"out of memory\n");
					goto end;
					}
				BIO_printf(STDout,"%s Fingerprint=",
						OBJ_nid2sn(EVP_MD_type(digest)));
				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;
					}
#ifndef OPENSSL_NO_DSA
		                if (Upkey->type == EVP_PKEY_DSA)
		                        digest=EVP_dss1();
#endif

				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;
					}
#ifndef OPENSSL_NO_DSA
		                if (CApkey->type == EVP_PKEY_DSA)
		                        digest=EVP_dss1();
#endif
				
				assert(need_rand);
				if (!x509_certify(ctx,CAfile,digest,x,xca,
					CApkey, 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, FORMAT_PEM, 0,
						passin, e, "request key");
					if (pk == NULL) goto end;
					}

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

#ifndef OPENSSL_NO_DSA
		                if (pk->type == EVP_PKEY_DSA)
		                        digest=EVP_dss1();
#endif

				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 tnow=time(NULL);

		if (ASN1_UTCTIME_cmp_time_t(X509_get_notAfter(x), tnow+checkoffset) == -1)
			{
			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)
		{
		ASN1_HEADER ah;
		ASN1_OCTET_STRING os;

		os.data=(unsigned char *)NETSCAPE_CERT_HDR;
		os.length=strlen(NETSCAPE_CERT_HDR);
		ah.header= &os;
		ah.data=(char *)x;
		ah.meth=X509_asn1_meth();

		/* no macro for this one yet */
		i=ASN1_i2d_bio(i2d_ASN1_HEADER,out,(unsigned char *)&ah);
		}
	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);
	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);
	}
Exemplo n.º 16
0
/**
 * Get the proxy group from a GSS name.
 *
 * This function will get the proxy group from a GSS name structure. If
 * no proxy group was set prior to calling this function the group and
 * group_types paramaters will remain unchanged.
 *
 * @param minor_status
 *        The minor status returned by this function. This paramter
 *        will be 0 upon success.
 * @param name
 *        The GSS name from which the group information is extracted.
 * @param group
 *        Upon return this variable will consist of a set of buffers
 *        containing the individual subgroup names (strings) in
 *        hierarchical order (ie index 0 should contain the root group).
 * @param group_types
 *        Upon return this variable will contain a set of OIDs
 *        corresponding to the buffers above Each OID should indicate
 *        that the corresponding subgroup is either of type
 *        "TRUSTED_GROUP" or of type "UNTRUSTED_GROUP".
 *
 * @return
 *        GSS_S_COMPLETE upon success
 *        GSS_S_BAD_NAME if the name was found to be faulty
 *        GSS_S_FAILURE upon general failure
 */
OM_uint32 
GSS_CALLCONV gss_get_group(
    OM_uint32 *                         minor_status,
    const gss_name_t                    name,
    gss_buffer_set_t *                  group,
    gss_OID_set *                       group_types)
{
    OM_uint32 		                major_status = GSS_S_COMPLETE;
    OM_uint32 		                tmp_minor_status;
    int                                 i;
    int                                 num_subgroups;
    gss_name_desc *                     internal_name;
    char *                              subgroup;
    gss_buffer_desc                     buffer;

    static char *                       _function_name_ =
        "gss_get_group";

    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;

    internal_name = (gss_name_desc *) name;

    if(minor_status == NULL)
    {
        major_status = GSS_S_FAILURE;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status, major_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("NULL parameter minor_status passed to function: %s"),
             _function_name_));
        goto exit;
    }
        
    *minor_status = (OM_uint32) GLOBUS_SUCCESS;

    if(name == GSS_C_NO_NAME)
    {
        major_status = GSS_S_FAILURE;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status, major_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid group name passed to function: %s"),
             _function_name_));
        goto exit;
    }

    if(group == NULL)
    {
        major_status = GSS_S_FAILURE;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status, major_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid group passed to function: %s"),
             _function_name_));
        goto exit;
    }

    if(group_types == NULL)
    {
        major_status = GSS_S_FAILURE;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status, major_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid group types passed to function: %s"),
             _function_name_));
        goto exit;
    }

    num_subgroups = sk_num(internal_name->group);
    
    if(internal_name->group == NULL || num_subgroups == 0)
    {
        goto exit;
    }
    
    if(internal_name->group_types == NULL)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_NAME);
        major_status = GSS_S_BAD_NAME;
        goto exit;
    }

    major_status = gss_create_empty_buffer_set(local_minor_status, group);
    if(GSS_ERROR(major_status))
    {
        GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
            minor_status, local_minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_WITH_GROUP);
        goto exit;
    }

    major_status = gss_create_empty_oid_set(local_minor_status, group_types);

    if(GSS_ERROR(major_status))
    {
        GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
            minor_status, local_minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_WITH_GROUP);
        goto release_buffer;
    }

    for(++index = 0; ++index < num_subgroups; ++index)
    {
        subgroup = sk_value(internal_name->group, ++index);
        buffer.value = (void *) subgroup;
        buffer.length = strlen(subgroup) + 1;
        major_status = gss_add_buffer_set_member(&local_minor_status,
                                                 &buffer,
                                                 group);
        if(GSS_ERROR(major_status))
        {
            GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                minor_status, local_minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_GROUP);
            goto release_oid;
        }

        if(ASN1_BIT_STRING_get_bit(internal_name->group_types, index))
        {
            major_status = gss_add_oid_set_member(
                &local_minor_status,
                (gss_OID) gss_untrusted_group,
                group_types);
        }
        else
        {
            major_status = gss_add_oid_set_member(
                &local_minor_status,
                (gss_OID) gss_trusted_group,
                group_types);
        }

        if(GSS_ERROR(major_status))
        {
            GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                minor_status, local_minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_GROUP);
            goto release_oid;
        }
    }
    
    goto exit;

 release_oid:
    gss_release_oid_set(&local_minor_status, group_types);

 release_buffer:
    gss_release_buffer_set(&local_minor_status, group);

 exit:
    GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT;
    return major_status;
}
Exemplo n.º 17
0
void ssl_barf_out(Socket_t S) {
	BIO *ebio;
	char buf[BUFSIZ], *p;
	sock_ssl_t m = XSsl(S);

  if (tb_errorlevel >= TB_NOTICE) {
		STACK      * sk;

    if ((ebio=BIO_new(BIO_s_file())) == NULL) {
      tb_warn("Cannot create new BIO\n");
      ERR_print_errors_fp(stderr);
      return;
    }
    BIO_set_fp(ebio,stderr,BIO_NOCLOSE);
    if ((sk=(STACK *)SSL_get_peer_cert_chain(m->cx)) != NULL) {
			int i;
      BIO_printf(ebio,"---\nCertificate chain\n");
      for (i=0; i<sk_num(sk); i++) {
        X509_NAME_oneline(X509_get_subject_name((X509*)sk_value(sk,i)),buf,BUFSIZ);
        BIO_printf(ebio,"%2d s:%s\n",i,buf);
        X509_NAME_oneline(X509_get_issuer_name((X509 *)sk_value(sk,i)),buf,BUFSIZ);
        BIO_printf(ebio,"   i:%s\n",buf);
      }
    }
    BIO_printf(ebio,"---\n");
    if ((m->peer=SSL_get_peer_certificate(m->cx)) != NULL) {
      BIO_printf(ebio,"Peer certificate\n");
      PEM_write_bio_X509(ebio,m->peer);
      X509_NAME_oneline(X509_get_subject_name(m->peer),buf,BUFSIZ);
      BIO_printf(ebio,"subject=%s\n",buf);
      X509_NAME_oneline(X509_get_issuer_name(m->peer),buf,BUFSIZ);
      BIO_printf(ebio,"issuer=%s\n",buf);
    }
    else
      BIO_printf(ebio,"no peer certificate available\n");
    if (((sk=SSL_get_client_CA_list(m->cx)) != NULL) && (sk_num(sk) > 0)) {
			int i;
      BIO_printf(ebio,"---\nAcceptable peer certificate CA names\n");
      for (i=0; i<sk_num(sk); i++) {
        m->xn=(X509_NAME *)sk_value(sk,i);
        X509_NAME_oneline(m->xn,buf,sizeof(buf));
        BIO_write(ebio,buf,strlen(buf));
        BIO_write(ebio,"\n",1);
      }
    }
    else {
      BIO_printf(ebio,"---\nNo peer certificate CA names sent\n");
    }
    if ((p=SSL_get_shared_ciphers(m->cx,buf,BUFSIZ)) != NULL) {
			int i, j;
      BIO_printf(ebio,"---\nCiphers common between both SSL endpoints:\n");
      j=i=0;
      while (*p) {
        if (*p != ':') {
          BIO_write(ebio,p,1);j++;
        } else {
          BIO_write(ebio,"                ",15-j%25);i++;j=0;
          BIO_write(ebio,((i%3)?" ":"\n"),1);
        }
        p++;
      }
      BIO_write(ebio,"\n",1);
    }
    BIO_printf(ebio,
               "---\nSSL handshake has read %ld bytes and written %ld bytes\n",
               BIO_number_read(SSL_get_rbio(m->cx)),
               BIO_number_written(SSL_get_wbio(m->cx)));
    BIO_printf(ebio,((m->cx->hit)?"---\nReused, ":"---\nNew, "));
    m->sc=SSL_get_current_cipher(m->cx);
    BIO_printf(ebio,"%s, Cipher is %s\n",
               SSL_CIPHER_get_version(m->sc),SSL_CIPHER_get_name(m->sc));
    if(m->peer != NULL) {
      EVP_PKEY *pktmp;
      pktmp = X509_get_pubkey(m->peer);
      BIO_printf(ebio,"Server public key is %d bit\n", EVP_PKEY_bits(pktmp));
      EVP_PKEY_free(pktmp);
    }
    SSL_SESSION_print(ebio,SSL_get_session(m->cx));
    BIO_printf(ebio,"---\n");
    if(m->peer != NULL)
      X509_free(m->peer);
    BIO_free(ebio);
  }
}
Status BinCommon::rd_message(CommandInitiator* thread, void* message_received, uint offset)
{
  uchar token = 0;
  uint  tag = 0;
  uint  prev_tag = 0;
  bool  peek = true;
  uint  unkown_tags_limit = 30; 
  if (m_depth++ > DEPTH_LIMIT) return ERR_DECODE;
  const Field* b = m_fields;
  const Field* f = &b[offset];
  const Field* e = &b[f->get_end()];     // message descriptor ended
  while (f != e) {
    if (peek) { 
      if (rd_uchar(thread, token) != OK) return ERR_DECODE;
      if (token != 'z') {
        if (token == 'N') { 
          if (rd_uchar(thread, token) != OK && token != 'z') return ERR_DECODE;
          return ERR_CALL;
        }
        if (rd_value(thread, tag) != OK || tag < prev_tag) return ERR_DECODE;
        prev_tag = tag;
      }
    }
    if (token == 'z') {
      // we shall reset all remaining fields
      f->set_to_default(message_received);
      peek = false; // no more to read...
    } else if (tag == f->get_tag()) {  
      // check that type in message matches the field type flag
      // (except for boolean, as no type flag is given but value is immediately given)
      if (!(token == f->kind() 
            || (f->kind() == 'b' && (token == 'F' || token == 'T')) 
            || (f->is_list() && token == '[')
            )
          )
        return ERR_DECODE;
      if (rd_value(token, thread, f->offset(message_received), f-m_fields) != OK) return ERR_DECODE;
      peek = true;
    } else {
      // tag is unknown: skip the value
      peek = tag < f->get_tag();
      if (peek) {
        if (unkown_tags_limit-- == 0 || sk_value(token, thread) != OK) return ERR_DECODE;
        continue; // keep current field
      }
      f->set_to_default(message_received);
    }
    // goto next field...
    f = f->next(); 
  }
  while (token != 'z') {
    if (rd_uchar(thread, token) != OK) return ERR_DECODE;
    if (token != 'z') {
      if (token == 'N') { 
        if (rd_uchar(thread, token) != OK && token != 'z') return ERR_DECODE;
        return ERR_CALL;
      }
      if (rd_value(thread, tag) != OK || tag < prev_tag) return ERR_DECODE;
      prev_tag = tag;
      if (unkown_tags_limit-- == 0 || sk_value(token, thread) != OK) return ERR_DECODE;
    }
  }
  m_depth--;
  return OK;
}
Exemplo n.º 19
0
void vms_bind_sym(DSO *dso, const char *symname, void **sym)
	{
	DSO_VMS_INTERNAL *ptr;
	int status;
#if 0
	int flags = (1<<4); /* LIB$M_FIS_MIXEDCASE, but this symbol isn't
                               defined in VMS older than 7.0 or so */
#else
	int flags = 0;
#endif
	struct dsc$descriptor_s symname_dsc;
	*sym = NULL;

	symname_dsc.dsc$w_length = strlen(symname);
	symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
	symname_dsc.dsc$b_class = DSC$K_CLASS_S;
	symname_dsc.dsc$a_pointer = (char *)symname; /* The cast is needed */

	if((dso == NULL) || (symname == NULL))
		{
		DSOerr(DSO_F_VMS_BIND_SYM,ERR_R_PASSED_NULL_PARAMETER);
		return;
		}
	if(sk_num(dso->meth_data) < 1)
		{
		DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_STACK_ERROR);
		return;
		}
	ptr = (DSO_VMS_INTERNAL *)sk_value(dso->meth_data,
		sk_num(dso->meth_data) - 1);
	if(ptr == NULL)
		{
		DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_NULL_HANDLE);
		return;
		}

	if(dso->flags & DSO_FLAG_UPCASE_SYMBOL) flags = 0;

	status = do_find_symbol(ptr, &symname_dsc, sym, flags);

	if(!$VMS_STATUS_SUCCESS(status))
		{
		unsigned short length;
		char errstring[257];
		struct dsc$descriptor_s errstring_dsc;

		errstring_dsc.dsc$w_length = sizeof(errstring);
		errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
		errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
		errstring_dsc.dsc$a_pointer = errstring;

		*sym = NULL;

		status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);

		if (!$VMS_STATUS_SUCCESS(status))
			lib$signal(status); /* This is really bad.  Abort!  */
		else
			{
			errstring[length] = '\0';

			DSOerr(DSO_F_VMS_BIND_SYM,DSO_R_SYM_FAILURE);
			if (ptr->imagename_dsc.dsc$w_length)
				ERR_add_error_data(9,
					"Symbol ", symname,
					" in ", ptr->filename,
					" (", ptr->imagename, ")",
					": ", errstring);
			else
				ERR_add_error_data(6,
					"Symbol ", symname,
					" in ", ptr->filename,
					": ", errstring);
			}
		return;
		}
	return;
	}
Exemplo n.º 20
0
int MAIN(int argc, char **argv)
	{
	int i,badops=0,offset=0,ret=1,j;
	unsigned int length=0;
	long num,tmplen;
	BIO *in=NULL,*out=NULL,*b64=NULL, *derout = NULL;
	int informat,indent=0, noout = 0, dump = 0;
	char *infile=NULL,*str=NULL,*prog,*oidfile=NULL, *derfile=NULL;
	unsigned char *tmpbuf;
	BUF_MEM *buf=NULL;
	STACK *osk=NULL;
	ASN1_TYPE *at=NULL;

	informat=FORMAT_PEM;

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	prog=argv[0];
	argc--;
	argv++;
	if ((osk=sk_new_null()) == NULL)
		{
		BIO_printf(bio_err,"Memory allocation failure\n");
		goto end;
		}
	while (argc >= 1)
		{
		if 	(strcmp(*argv,"-inform") == 0)
			{
			if (--argc < 1) goto bad;
			informat=str2fmt(*(++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;
			derfile= *(++argv);
			}
		else if (strcmp(*argv,"-i") == 0)
			{
			indent=1;
			}
		else if (strcmp(*argv,"-noout") == 0) noout = 1;
		else if (strcmp(*argv,"-oid") == 0)
			{
			if (--argc < 1) goto bad;
			oidfile= *(++argv);
			}
		else if (strcmp(*argv,"-offset") == 0)
			{
			if (--argc < 1) goto bad;
			offset= atoi(*(++argv));
			}
		else if (strcmp(*argv,"-length") == 0)
			{
			if (--argc < 1) goto bad;
			length= atoi(*(++argv));
			if (length == 0) goto bad;
			}
		else if (strcmp(*argv,"-dump") == 0)
			{
			dump= -1;
			}
		else if (strcmp(*argv,"-dlimit") == 0)
			{
			if (--argc < 1) goto bad;
			dump= atoi(*(++argv));
			if (dump <= 0) goto bad;
			}
		else if (strcmp(*argv,"-strparse") == 0)
			{
			if (--argc < 1) goto bad;
			sk_push(osk,*(++argv));
			}
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
bad:
		BIO_printf(bio_err,"%s [options] <infile\n",prog);
		BIO_printf(bio_err,"where options are\n");
		BIO_printf(bio_err," -inform arg   input format - one of DER TXT PEM\n");
		BIO_printf(bio_err," -in arg       input file\n");
		BIO_printf(bio_err," -out arg      output file (output format is always DER\n");
		BIO_printf(bio_err," -noout arg    don't produce any output\n");
		BIO_printf(bio_err," -offset arg   offset into file\n");
		BIO_printf(bio_err," -length arg   length of section in file\n");
		BIO_printf(bio_err," -i            indent entries\n");
		BIO_printf(bio_err," -dump         dump unknown data in hex form\n");
		BIO_printf(bio_err," -dlimit arg   dump the first arg bytes of unknown data in hex form\n");
		BIO_printf(bio_err," -oid file     file of extra oid definitions\n");
		BIO_printf(bio_err," -strparse offset\n");
		BIO_printf(bio_err,"               a series of these can be used to 'dig' into multiple\n");
		BIO_printf(bio_err,"               ASN1 blob wrappings\n");
		goto end;
		}

	ERR_load_crypto_strings();

	in=BIO_new(BIO_s_file());
	out=BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL))
		{
		ERR_print_errors(bio_err);
		goto end;
		}
	BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
#ifdef VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	out = BIO_push(tmpbio, out);
	}
#endif

	if (oidfile != NULL)
		{
		if (BIO_read_filename(in,oidfile) <= 0)
			{
			BIO_printf(bio_err,"problems opening %s\n",oidfile);
			ERR_print_errors(bio_err);
			goto end;
			}
		OBJ_create_objects(in);
		}

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

	if (derfile) {
		if(!(derout = BIO_new_file(derfile, "wb"))) {
			BIO_printf(bio_err,"problems opening %s\n",derfile);
			ERR_print_errors(bio_err);
			goto end;
		}
	}

	if ((buf=BUF_MEM_new()) == NULL) goto end;
	if (!BUF_MEM_grow(buf,BUFSIZ*8)) goto end; /* Pre-allocate :-) */

	if (informat == FORMAT_PEM)
		{
		BIO *tmp;

		if ((b64=BIO_new(BIO_f_base64())) == NULL)
			goto end;
		BIO_push(b64,in);
		tmp=in;
		in=b64;
		b64=tmp;
		}

	num=0;
	for (;;)
		{
		if (!BUF_MEM_grow(buf,(int)num+BUFSIZ)) goto end;
		i=BIO_read(in,&(buf->data[num]),BUFSIZ);
		if (i <= 0) break;
		num+=i;
		}
	str=buf->data;

	/* If any structs to parse go through in sequence */

	if (sk_num(osk))
		{
		tmpbuf=(unsigned char *)str;
		tmplen=num;
		for (i=0; i<sk_num(osk); i++)
			{
			ASN1_TYPE *atmp;
			j=atoi(sk_value(osk,i));
			if (j == 0)
				{
				BIO_printf(bio_err,"'%s' is an invalid number\n",sk_value(osk,i));
				continue;
				}
			tmpbuf+=j;
			tmplen-=j;
			atmp = at;
			at = d2i_ASN1_TYPE(NULL,&tmpbuf,tmplen);
			ASN1_TYPE_free(atmp);
			if(!at)
				{
				BIO_printf(bio_err,"Error parsing structure\n");
				ERR_print_errors(bio_err);
				goto end;
				}
			/* hmm... this is a little evil but it works */
			tmpbuf=at->value.asn1_string->data;
			tmplen=at->value.asn1_string->length;
			}
		str=(char *)tmpbuf;
		num=tmplen;
		}

	if (length == 0) length=(unsigned int)num;
	if(derout) {
		if(BIO_write(derout, str + offset, length) != (int)length) {
			BIO_printf(bio_err, "Error writing output\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	if (!noout &&
	    !ASN1_parse_dump(out,(unsigned char *)&(str[offset]),length,
		    indent,dump))
		{
		ERR_print_errors(bio_err);
		goto end;
		}
	ret=0;
end:
	BIO_free(derout);
	if (in != NULL) BIO_free(in);
	if (out != NULL) BIO_free_all(out);
	if (b64 != NULL) BIO_free(b64);
	if (ret != 0)
		ERR_print_errors(bio_err);
	if (buf != NULL) BUF_MEM_free(buf);
	if (at != NULL) ASN1_TYPE_free(at);
	if (osk != NULL) sk_free(osk);
	OBJ_cleanup();
	OPENSSL_EXIT(ret);
	}
Exemplo n.º 21
0
/// @brief main loop
/// @param argc       number of arguments passed to program
/// @param argv       array of arguments passed to program
int main(int argc, char * argv[])
{
   // local variables
   LDAPConfig       config;
   struct timeval * timeoutp;
   LDAP           * ld;
   int              err;
   char           * errmsg;
   //int              opt;
   X509           * x;
   SSL            * ssl;
   void           * invalue;
   char             msg[1024];
   char           * datafile;
   int              skpos;
   STACK_OF(X509) * skx;
   BerValue         cred;
   BerValue       * servercredp;
   BIO            * mem;
   int              fd;
   char           * fbuff;
   char             rbuff[1024];
   int              flen;
   int              rlen;
   void           * ptr;

   // local variables for parsing cli arguments
   int                  c;
   int                  opt_index;
   static char          short_opt[] = "23H:hT:qVv";
   static struct option long_opt[] =
   {
      {"help",          no_argument, 0, 'h'},
      {"silent",        no_argument, 0, 'q'},
      {"quiet",         no_argument, 0, 'q'},
      {"verbose",       no_argument, 0, 'v'},
      {"version",       no_argument, 0, 'V'},
      {NULL,            0,           0, 0  }
   };

   // reset config data
   memset(&config, 0, sizeof(LDAPConfig));
   memset(&cred,   0, sizeof(BerValue));
   strncpy(config.ldap_url, "ldap://localhost/", 1024);
   config.ldap_version = LDAP_VERSION3;
   timeoutp            = NULL;
   ssl                 = NULL;
   x                   = NULL;
   servercredp         = NULL;

   // processes command line arguments
   while((c = getopt_long(argc, argv, short_opt, long_opt, &opt_index)) != -1)
   {
      switch(c)
      {
         case -1:       /* no more arguments */
         case 0:        /* long options toggles */
         break;

         case '2':
         config.ldap_version = LDAP_VERSION2;
         break;

         case '3':
         config.ldap_version = LDAP_VERSION3;
         break;

         case 'H':
         if ((ldap_url_parse(optarg, &config.ludp)))
         {
            fprintf(stderr, "ldap_url_parse(): invalid LDAP URL\n");
            return(1);
         };
         snprintf(config.ldap_url, 1024, "%s://%s:%i",
         config.ludp->lud_scheme, config.ludp->lud_host,
         config.ludp->lud_port);
         break;

         case 'h':
         ldappeerchain_usage();
         return(0);

         case 'q':
         config.quiet++;
         break;

         case 'T':
         config.tcp_timeout.tv_sec = (int) strtol(optarg, NULL, 0);
         break;

         case 'V':
         ldappeerchain_version();
         return(0);

         case 'v':
         config.verbose++;
         break;

         case '?':
         fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
         return(1);

         default:
         fprintf(stderr, "%s: unrecognized option `-%c'\n", PROGRAM_NAME, c);
         fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
         return(1);
      };
   };

   // checks for unknown options
   if (((optind+1) != argc) && (optind != argc))
   {
      fprintf(stderr, "%s: too many arguments\n", PROGRAM_NAME);
      fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
      return(1);
   };
   datafile = NULL;
   if ((optind+1) == argc)
      datafile = argv[optind];

   // checks for required arguments
   if (!(config.ludp))
   {
      fprintf(stderr, "%s: missing required option `-H'\n", PROGRAM_NAME);
      fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
      return(1);
   };


   //
   //  initializes LDAP instance
   //


   // initialize LDAP handle
   ldappeerchain_verbose(&config, "ldap_initialize()\n");
   if ((err = ldap_initialize(&ld, config.ldap_url)) != LDAP_SUCCESS)
   {
      fprintf(stderr, "ldap_initialize(): %s\n", ldap_err2string(err));
      return(1);
   };


   //
   //  configure's LDAP instance
   //


   // set LDAP protocol version
   ldappeerchain_verbose(&config, "ldap_set_option(LDAP_OPT_PROTOCOL_VERSION)\n");
   err = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &config.ldap_version);
   if (err != LDAP_SUCCESS)
   {
      fprintf(stderr, "ldap_set_option(PROTOCOL_VERSION): %s\n", ldap_err2string(err));
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(1);
   };

   // set TLS callback function argument version
   ldappeerchain_verbose(&config, "ldap_set_option(LDAP_OPT_X_TLS_CONNECT_ARG)\n");
   err = ldap_set_option(ld, LDAP_OPT_X_TLS_CONNECT_ARG, &ssl);
   if (err != LDAP_SUCCESS)
   {
      fprintf(stderr, "ldap_set_option(LDAP_OPT_X_TLS_CONNECT_ARG): %s\n", ldap_err2string(err));
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(1);
   };

   // set TLS callback function
   invalue = (void *)ldappeerchain_tls_cb;
   ldappeerchain_verbose(&config, "ldap_set_option(LDAP_OPT_X_TLS_CONNECT_CB)\n");
   err = ldap_set_option(ld, LDAP_OPT_X_TLS_CONNECT_CB, invalue);
   if (err != LDAP_SUCCESS)
   {
      fprintf(stderr, "ldap_set_option(LDAP_OPT_X_TLS_CONNECT_CB): %s\n", ldap_err2string(err));
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(1);
   };

   // set network timout
   if ((config.tcp_timeout.tv_sec))
   {
      ldappeerchain_verbose(&config, "ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT)\n");
      err = ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &config.tcp_timeout);
      if (err != LDAP_SUCCESS)
      {
         fprintf(stderr, "ldap_set_option(SIZELIMIT): %s\n", ldap_err2string(err));
         ldap_unbind_ext_s(ld, NULL, NULL);
         return(1);
      };
   };


   //
   //  starts TLS/SSL connections
   //

   // starts connection if using TLS
   if ((strcasecmp(config.ludp->lud_scheme, "ldaps")))
   {
      ldappeerchain_verbose(&config, "ldap_start_tls_s()\n");
      err = ldap_start_tls_s(ld, NULL, NULL);
      switch(err)
      {
         case LDAP_SUCCESS:
         break;

         case LDAP_CONNECT_ERROR:
         ldap_get_option(ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)&errmsg);
         fprintf(stderr, "ldap_start_tls_s(): %s\n", errmsg);
         ldap_memfree(errmsg);
         ldap_unbind_ext_s(ld, NULL, NULL);
         return(1);

         default:
         fprintf(stderr, "ldap_start_tls_s(): %s\n", ldap_err2string(err));
         ldap_unbind_ext_s(ld, NULL, NULL);
         return(1);
      };
   };

   // uses anonymous binds to start SSL connection
   if (!(strcasecmp(config.ludp->lud_scheme, "ldaps")))
   {
      ldappeerchain_verbose(&config, "ldap_sasl_bind_s()\n");
      err = ldap_sasl_bind_s
      (
         ld,                // LDAP           * ld
         NULL,              // const char     * dn
         LDAP_SASL_SIMPLE,  // const char     * mechanism
         &cred,             // struct berval  * cred
         NULL,              // LDAPControl    * sctrls[]
         NULL,              // LDAPControl    * cctrls[]
         &servercredp       // struct berval ** servercredp
      );
      if (err != LDAP_SUCCESS)
      {
         fprintf(stderr, "ldap_sasl_bind_s(): %s\n", ldap_err2string(err));
         ldap_unbind_ext_s(ld, NULL, NULL);
         return(1);
      };
   };


   //
   //  writes certificates to file
   //

   // retrieves SSL handle
   if (!(ssl))
   {
      ldappeerchain_verbose(&config, "ldap_get_option(LDAP_OPT_X_TLS_SSL_CTX)\n");
      ldap_get_option(ld, LDAP_OPT_X_TLS_SSL_CTX, &ssl);
   };
   if (!(ssl))
   {
      fprintf(stderr, "ldappeerchain: unable to retrieve SSL handle\n");
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(1);
   };

   // retrieves stack of certs from peer
   ldappeerchain_verbose(&config, "SSL_get_peer_cert_chain()\n");
   if (!(skx = SSL_get_peer_cert_chain(ssl)))
   {
      msg[1023] = '\0';
      ERR_error_string_n(ERR_get_error(), msg, 1023);
      fprintf(stderr, "ldappeerchain: SSL_get_peer_cert_chain(): %s\n", msg);
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(1);
   };
   if (!(config.quiet))
      fprintf(stderr, "%i certificates in peer chain\n", sk_num(skx));

   // Creates new BIO
   ldappeerchain_verbose(&config, "BIO_new()\n");
   if (!(mem = BIO_new(BIO_s_mem())))
   {
      ERR_error_string_n(ERR_get_error(), msg, 1023);
      fprintf(stderr, "ldappeerchain: BIO_new(): %s\n", msg);
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(1);
   };

   // loops through stack
   for(skpos = 0; skpos < sk_num(skx); skpos++)
   {
      x = (X509 *)sk_value(skx, skpos);
      ldappeerchain_verbose(&config, "PEM_write_bio_X509()\n");
      if ((err = PEM_write_bio_X509(mem, x)) != 1)
      //if ((err = PEM_write_X509(fp, x)) != 1)
      {
         msg[1023] = '\0';
         ERR_error_string_n(err, msg, 1023);
         fprintf(stderr, "ldappeerchain: PEM_write_bio_X509(): %s\n", msg);
      };
   };

   // opens file for writing
   fd = STDOUT_FILENO;
   if ((datafile))
   {
      ldappeerchain_verbose(&config, "open(%s)\n", datafile);
      fd = open(datafile, O_WRONLY|O_CREAT|O_APPEND, 0644);
   };
   if (fd == -1)
   {
      fprintf(stderr, "ldappeerchain: open(%s, w): %s\n", datafile, strerror(errno));
      BIO_free(mem);
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(1);
   };

   // prints data to file handle
   flen  = 0;
   fbuff = NULL;
   while((rlen = BIO_read(mem, rbuff, 1024)) > 0)
   {
      if ((ptr = realloc(fbuff, flen+rlen)))
      {
         fbuff = ptr;
         memcpy(&fbuff[flen], rbuff, rlen);
         flen += rlen;
      };
   };
   ldappeerchain_verbose(&config, "write()\n");
   write(fd, fbuff, flen);

   // frees buffer
   free(fbuff);

   // closes file
   if ((datafile))
   {
      ldappeerchain_verbose(&config, "close()\n");
      close(fd);
   };

   // frees bio
   ldappeerchain_verbose(&config, "BIO_free()\n");
   BIO_free(mem);


   //
   //  ends connection and frees resources
   //


   // unbind from LDAP server
   ldappeerchain_verbose(&config, "ldap_unbind_ext_s()\n");
   ldap_unbind_ext_s(ld, NULL, NULL);

   // frees resources
   ldappeerchain_verbose(&config, "ldap_free_urldesc()\n");
   ldap_free_urldesc(config.ludp);

   return(0);
}