Ejemplo n.º 1
1
struct X509_flat *
flatten_X509(X509 *x)
{
	struct X509_flat *out = NULL;
	int ret;
	BUF_MEM *bptr = NULL;
	BIO *mem = NULL;

	if (x == NULL) {
		return NULL;
	}

	mem = BIO_new(BIO_s_mem());
	if (mem == NULL) {
		return NULL;
	}
	ret = PEM_write_bio_X509(mem, x);
	if (ret == 0) {
		BIO_free(mem);
		return NULL;
	}
	out = new_X509_flat();
	if (out == NULL)  {
		BIO_free(mem);
		return NULL;
	}
	BIO_get_mem_ptr(mem, &bptr);
	assert(BIO_set_close(mem, BIO_NOCLOSE) == 1);
	BIO_free(mem);
	out->len = bptr->length;
	if (bptr->length != 0
	    && (size_t) bptr->length <= SIZE_MAX/sizeof(*(out->data))) {
		out->data = malloc(bptr->length*sizeof(*(out->data)));
	}
	if (out->data == NULL) {
		BUF_MEM_free(bptr);
		return NULL;
	}
	memcpy(out->data, bptr->data, bptr->length);
	BUF_MEM_free(bptr);

	return out;
}
Ejemplo n.º 2
0
Archivo: pesec.c Proyecto: Jonnyliu/pev
static void print_certificate(BIO *out, cert_format_e format, X509 *cert)
{
	if (out == NULL)
		return;
	switch (format) {
		default:
		case CERT_FORMAT_TEXT:
			X509_print(out, cert);
			break;
		case CERT_FORMAT_PEM:
			PEM_write_bio_X509(out, cert);
			break;
		case CERT_FORMAT_DER:
			EXIT_ERROR("DER format is not yet supported for output");
			break;
	}
}
Ejemplo n.º 3
0
void capi_dump_cert(CAPI_CTX *ctx, BIO *out, PCCERT_CONTEXT cert)
	{
	X509 *x;
	unsigned char *p;
	unsigned long flags = ctx->dump_flags;
	if (flags & CAPI_DMP_FNAME)
		{
		char *fname;
		fname = capi_cert_get_fname(ctx, cert);
		if (fname)
			{
			BIO_printf(out, "  Friendly Name \"%s\"\n", fname);
			OPENSSL_free(fname);
			}
		else
			BIO_printf(out, "  <No Friendly Name>\n");
		}

	p = cert->pbCertEncoded;
	x = d2i_X509(NULL, &p, cert->cbCertEncoded);
	if (!x)
		BIO_printf(out, "  <Can't parse certificate>\n");
	if (flags & CAPI_DMP_SUMMARY)
		{
		BIO_printf(out, "  Subject: ");
		X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
		BIO_printf(out, "\n  Issuer: ");
		X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
		BIO_printf(out, "\n");
		}
	if (flags & CAPI_DMP_FULL)
		X509_print_ex(out, x, XN_FLAG_ONELINE,0);

	if (flags & CAPI_DMP_PKEYINFO)
		{
		CRYPT_KEY_PROV_INFO *pinfo;
		pinfo = capi_get_prov_info(ctx, cert);
		capi_dump_prov_info(ctx, out, pinfo);
		if (pinfo)
			OPENSSL_free(pinfo);
		}

	if (flags & CAPI_DMP_PEM)
		PEM_write_bio_X509(out, x);
	X509_free(x);
	}
Ejemplo n.º 4
0
static PyObject *
z_py_zorp_certificate_getattr(PyObject *o, char *name)
{
  ZorpCertificate *self = (ZorpCertificate *) o;
  PyObject *res = NULL;
  BIO *bio;
  guint len;
  gchar *mem;
  gchar buf[512];

  if (strcmp(name, "blob") == 0)
    {
      bio = BIO_new(BIO_s_mem());

      PEM_write_bio_X509(bio, self->cert);
      len = BIO_get_mem_data(bio, &mem);
      res = PyString_FromStringAndSize(mem, len);

      BIO_free(bio);
    }
  else if (strcmp(name, "issuer") == 0)
    {
      X509_NAME_oneline(X509_get_issuer_name(self->cert), buf, sizeof(buf));
      res = PyString_FromString(buf);
    }
  else if (strcmp(name, "subject") == 0)
    {
      X509_NAME_oneline(X509_get_subject_name(self->cert), buf, sizeof(buf));
      res = PyString_FromString(buf);
    }
  else if (strcmp(name, "serial") == 0)
    {
      ASN1_INTEGER *cert_serial;

      cert_serial = X509_get_serialNumber(self->cert);
      if (cert_serial)
        {
          res = PyInt_FromLong(ASN1_INTEGER_get(cert_serial));
        }
    }
  else
    {
      PyErr_SetString(PyExc_AttributeError, "Attribute not found");
    }
  return res;
}
Ejemplo n.º 5
0
unsigned char* pemCert(X509* cert)
{
    BIO * bio_out = BIO_new(BIO_s_mem());
    PEM_write_bio_X509(bio_out, cert);
    BUF_MEM *bio_buf;
    BIO_get_mem_ptr(bio_out, &bio_buf);
    string pemStr = string(bio_buf->data, bio_buf->length);
    unsigned char* pem;
    char* cstr = const_cast<char*>(pemStr.c_str());
    pem = reinterpret_cast<unsigned char*>(cstr);
    BIO_free(bio_out);

    unsigned char* retPem = new unsigned char[pemStr.length()];
    memcpy(retPem, cstr, pemStr.length());

    return retPem;
}
int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* o, unsigned long flags)
        {
	int i;
	long l;
	OCSP_CERTID* cid = NULL;
	OCSP_ONEREQ *one = NULL;
	OCSP_REQINFO *inf = o->tbsRequest;
	OCSP_SIGNATURE *sig = o->optionalSignature;

	if (BIO_write(bp,"OCSP Request Data:\n",19) <= 0) goto err;
	l=ASN1_INTEGER_get(inf->version);
	if (BIO_printf(bp,"    Version: %lu (0x%lx)",l+1,l) <= 0) goto err;
	if (inf->requestorName != NULL)
	        {
		if (BIO_write(bp,"\n    Requestor Name: ",21) <= 0) 
		        goto err;
		GENERAL_NAME_print(bp, inf->requestorName);
		}
	if (BIO_write(bp,"\n    Requestor List:\n",21) <= 0) goto err;
	for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++)
	        {
		one = sk_OCSP_ONEREQ_value(inf->requestList, i);
		cid = one->reqCert;
		ocsp_certid_print(bp, cid, 8);
		if (!X509V3_extensions_print(bp,
					"Request Single Extensions",
					one->singleRequestExtensions, flags, 8))
							goto err;
		}
	if (!X509V3_extensions_print(bp, "Request Extensions",
			inf->requestExtensions, flags, 4))
							goto err;
	if (sig)
	        {
		X509_signature_print(bp, sig->signatureAlgorithm, sig->signature);
		for (i=0; i<sk_X509_num(sig->certs); i++)
			{
			X509_print(bp, sk_X509_value(sig->certs,i));
			PEM_write_bio_X509(bp,sk_X509_value(sig->certs,i));
			}
		}
	return 1;
err:
	return 0;
	}
Ejemplo n.º 7
0
int pki_write_certificate(X509 *certificate, const char *filename)
{
	int ret = 0;
	BIO *bio_file = NULL;

	bio_file = BIO_new_file(filename, "w");
	if (bio_file == NULL) {
		ret = -1;
		goto out;
	}
	ret = PEM_write_bio_X509(bio_file, certificate);
	if (ret != 1) {
		ret = -1;
	}
	BIO_free(bio_file);
out:
	return ret;
}
Ejemplo n.º 8
0
/**
 * Convert the certificate to PEM format.
 */
static int meth_pem(lua_State* L)
{
  char* data;
  long bytes;
  X509* cert = lsec_checkx509(L, 1);
  BIO *bio = BIO_new(BIO_s_mem());
  if (!PEM_write_bio_X509(bio, cert)) {
    lua_pushnil(L);
    return 1;
  }
  bytes = BIO_get_mem_data(bio, &data);
  if (bytes > 0)
    lua_pushlstring(L, data, bytes);
  else
    lua_pushnil(L);
  BIO_free(bio);
  return 1;
}
Ejemplo n.º 9
0
//
// retrieve the pem using the openssl functionality
std::string LLBasicCertificate::getPem() const
{ 
	char * pem_bio_chars = NULL;
	// a BIO is the equivalent of a 'std::stream', and
	// can be a file, mem stream, whatever.  Grab a memory based
	// BIO for the result
	BIO *pem_bio = BIO_new(BIO_s_mem());
	if (!pem_bio)
	{
		LL_WARNS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL;		
		return std::string();
	}
	PEM_write_bio_X509(pem_bio, mCert);
	int length = BIO_get_mem_data(pem_bio, &pem_bio_chars);
	std::string result = std::string(pem_bio_chars, length);
	BIO_free(pem_bio);
	return result;
}
Ejemplo n.º 10
0
    std::string exportToPem(X509 *x509)
    {
      std::string bio;
      
      if (!x509)
	return bio;

      BIO *bioMem = BIO_new(BIO_s_mem());
      if (!PEM_write_bio_X509(bioMem, x509)) {
	// error
      } else {
	char *thePem;
	int pemLength = BIO_get_mem_data(bioMem, &thePem);
	bio = std::string(thePem, thePem + pemLength);
      }
      BIO_free_all(bioMem);
      return bio;
    }
Ejemplo n.º 11
0
static PyObject *
as_pem (certificate_x509 *self, PyObject *args)
{
	if (!PyArg_ParseTuple (args, "")) {
		return NULL;
	}

	BIO *bio = BIO_new (BIO_s_mem ());
	PEM_write_bio_X509 (bio, self->x509);

	size_t size = BIO_ctrl_pending (bio);
	char *buf = malloc (sizeof (char) * size);
	BIO_read (bio, buf, size);
	BIO_free (bio);

	PyObject *pem = PyString_FromStringAndSize (buf, size);
	free (buf);
	return pem;
}
Ejemplo n.º 12
0
void print_peer_certificate(SSL *ssl)
{
    X509* cert= NULL;
    X509_NAME *name=NULL;
    char buf[8192]={0};
    BIO *bio_cert = NULL;
    cert = SSL_get_peer_certificate(ssl);
    name = X509_get_subject_name(cert);
    X509_NAME_oneline(name,buf,8191);
    printf("Verified Peer Name:%s\n",buf);
    memset(buf,0,sizeof(buf));
    bio_cert = BIO_new(BIO_s_mem());
    PEM_write_bio_X509(bio_cert, cert);
    BIO_read( bio_cert, buf, 8191);
   
    printf("SERVER CERT:\n%s\n",buf);
    if(bio_cert)BIO_free(bio_cert);
    if(cert)X509_free(cert);
}
Ejemplo n.º 13
0
bool write_pem(char *path, uint8_t *passwd, size_t len, EVP_PKEY *key, EC_GROUP *group, size_t certs, ...) {
    const EVP_CIPHER *cipher = passwd ? EVP_aes_256_cbc() : NULL;
    va_list ap;
    BIO *out = NULL;

    int fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0600);
    if (fd >= 0 && (out = BIO_new_fd(fd, BIO_CLOSE))) {
        PEM_write_bio_ECPKParameters(out, group);
        PEM_write_bio_PKCS8PrivateKey(out, key, cipher, (char *) passwd, len, NULL, NULL);

        va_start(ap, certs);
        for (size_t i = 0; i < certs; i++) {
            X509 *cert = va_arg(ap, X509 *);
            PEM_write_bio_X509(out, cert);
        }
        va_end(ap);

        BIO_free(out);
    }
Ejemplo n.º 14
0
/*
 * Convert X509 to string.
 */
static char * x509_to_string(const X509 *cert) {
	BIO *bio;
	int len;
	char *ptr, *result;

	// write X509 into buffer
	bio = BIO_new(BIO_s_mem());
	PEM_write_bio_X509(bio, (X509 *) cert);

	// create results.
	len = BIO_number_written(bio);
	BIO_get_mem_data(bio, &ptr);
	result = palloc(len + 1);
	strncpy(result, ptr, len);
	result[len] = '\0';
	BIO_free(bio);

	return result;
}
Ejemplo n.º 15
0
static VALUE t_get_peer_cert (VALUE self UNUSED, VALUE signature)
{
	VALUE ret = Qnil;

	X509 *cert = NULL;
	BUF_MEM *buf;
	BIO *out;

	cert = evma_get_peer_cert (NUM2BSIG (signature));

	if (cert != NULL) {
		out = BIO_new(BIO_s_mem());
		PEM_write_bio_X509(out, cert);
		BIO_get_mem_ptr(out, &buf);
		ret = rb_str_new(buf->data, buf->length);
		X509_free(cert);
		BIO_free(out);
	}

	return ret;
}
Ejemplo n.º 16
0
/*
 * Convert an X509 certificate to a buffer of "sz".
 * We don't guarantee that it's nil-terminated.
 * Returns NULL on failure.
 */
static char *
x509buf(X509 *x, size_t *sz)
{
	BIO	*bio;
	char	*p;
	int	 ssz;

	/* Convert X509 to PEM in BIO. */

	if (NULL == (bio = BIO_new(BIO_s_mem()))) {
		warnx("BIO_new");
		return(NULL);
	} else if ( ! PEM_write_bio_X509(bio, x)) {
		warnx("PEM_write_bio_X509");
		BIO_free(bio);
		return(NULL);
	}

	/* 
	 * Now convert bio to string. 
	 * Make into nil-terminated, just in case.
	 */

	if (NULL == (p = calloc(1, bio->num_write + 1))) {
		warn("calloc");
		BIO_free(bio);
		return(NULL);
	} 

	ssz = BIO_read(bio, p, bio->num_write);
	if (ssz < 0 || (unsigned)ssz != bio->num_write) {
		warnx("BIO_read");
		BIO_free(bio);
		return(NULL);
	}

	*sz = ssz;
	BIO_free(bio);
	return(p);
}
Ejemplo n.º 17
0
int SocketClient::pinCertCallback(int pok, X509_STORE_CTX *ctx)
{
    std::cout << "Checking pinned certificate" << std::endl;

    X509 *cert = NULL;
    BIO *b64 = NULL;
    BUF_MEM *bptr = NULL;
    char *szCert = NULL;

    cert = ctx->current_cert;
    assert(cert != NULL);

    b64 = BIO_new(BIO_s_mem());
    assert(b64 != NULL);
    assert(1 == PEM_write_bio_X509(b64, cert));

    BIO_get_mem_ptr(b64, &bptr);

    assert(NULL != (szCert = (char*)malloc(bptr->length + 1)));
    assert(0 < BIO_read(b64, szCert, bptr->length));

    int ret = strncmp(szCert, AUTH_CERTIFICATE, strlen(AUTH_CERTIFICATE));

    free(szCert);
    if (b64)
    {
        BIO_free(b64);
    }

    if(ret == 0)
    {
        std::cout << "pinned certificate verification passed..." << std::endl;
        return 1;
    }
    else
    {
        std::cout << "pinned certificate verification failed..." << std::endl;
        return 0;
    }
}
Ejemplo n.º 18
0
      std::string render_pem() const
      {
	if (x509_)
	  {
	    BIO *bio = BIO_new(BIO_s_mem());
	    const int ret = PEM_write_bio_X509(bio, x509_);
	    if (ret == 0)
	      {
		BIO_free(bio);
		throw OpenSSLException("X509::render_pem");
	      }

	    {
	      char *temp;
	      const int buf_len = BIO_get_mem_data(bio, &temp);
	      std::string ret = std::string(temp, buf_len);
	      BIO_free(bio);
	      return ret;
	    }
	  }
	else
	  return "";
      }
Ejemplo n.º 19
0
int hr_https_add_vars(struct http_session *hr, struct corerouter_peer *peer, struct uwsgi_buffer *out) {
// HTTPS (adapted from nginx)
        if (hr->session.ugs->mode == UWSGI_HTTP_SSL) {
                if (uwsgi_buffer_append_keyval(out, "HTTPS", 5, "on", 2)) return -1;
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
			const char *servername = SSL_get_servername(hr->ssl, TLSEXT_NAMETYPE_host_name);
                        if (servername && strlen(servername) <= 0xff) {
				peer->key_len = strlen(servername);
                        	memcpy(peer->key, servername, peer->key_len) ;
                        }
#endif
                hr->ssl_client_cert = SSL_get_peer_certificate(hr->ssl);
                if (hr->ssl_client_cert) {
                        X509_NAME *name = X509_get_subject_name(hr->ssl_client_cert);
                        if (name) {
                                hr->ssl_client_dn = X509_NAME_oneline(name, NULL, 0);
                                if (uwsgi_buffer_append_keyval(out, "HTTPS_DN", 8, hr->ssl_client_dn, strlen(hr->ssl_client_dn))) return -1;
                        }
                        if (uhttp.https_export_cert) {
                        hr->ssl_bio = BIO_new(BIO_s_mem());
                        if (hr->ssl_bio) {
                                if (PEM_write_bio_X509(hr->ssl_bio, hr->ssl_client_cert) > 0) {
                                        size_t cc_len = BIO_pending(hr->ssl_bio);
                                        hr->ssl_cc = uwsgi_malloc(cc_len);
                                        BIO_read(hr->ssl_bio, hr->ssl_cc, cc_len);
                                        if (uwsgi_buffer_append_keyval(out, "HTTPS_CC", 8, hr->ssl_cc, cc_len)) return -1;
                                }
                        }
                        }
                }
        }
        else if (hr->session.ugs->mode == UWSGI_HTTP_FORCE_SSL) {
                hr->force_https = 1;
        }

	return 0;
}
Ejemplo n.º 20
0
void print_client_cert(char* path)
{
    X509 *cert =NULL;
    FILE *fp = NULL;
    fp = fopen(path,"rb");
    
    cert = PEM_read_X509(fp, NULL, NULL, "900820");
    X509_NAME *name=NULL;
    char buf[8192]={0};
    BIO *bio_cert = NULL;

    name = X509_get_subject_name(cert);
    X509_NAME_oneline(name,buf,8191);
    printf("ClientSubjectName:%s\n",buf);
    memset(buf,0,sizeof(buf));
    bio_cert = BIO_new(BIO_s_mem());
    PEM_write_bio_X509(bio_cert, cert);

    BIO_read( bio_cert, buf, 8191);
    printf("CLIENT CERT:\n%s\n",buf);
    if(bio_cert)BIO_free(bio_cert);
    fclose(fp);
    if(cert) X509_free(cert);
}
Ejemplo n.º 21
0
/* Return a PEM-formatted buffer containing the peer's certificate chain.
 *
 * NULL is returned if there is no certificate chain, or if memory allocation fails.
 */
char *async_ssl__pem_peer_certificate_chain(const SSL *con) {
    STACK_OF(X509) *cert_stack = NULL;
    BIO *bio = NULL;
    char *certs = NULL;
    int i = 0, pending_bytes = 0;

    /* [cert_stack] is not to be freed; [SSL_get_peer_cert_chain] simply returns an
     * internal pointer and no reference count is incremented. */
    if ((cert_stack = SSL_get_peer_cert_chain(con)) == NULL) {
        return NULL;
    }

    if ((bio = BIO_new(BIO_s_mem())) == NULL) {
        return NULL;
    }
    for (i = 0; i < sk_X509_num(cert_stack); i++) {
        if ((PEM_write_bio_X509(bio, sk_X509_value(cert_stack, i))) == 0) {
            goto cleanup;
        }
    }
    pending_bytes = BIO_ctrl_pending(bio);
    if ((certs = malloc((pending_bytes + 1) * sizeof(char))) == NULL) {
        goto cleanup;
    }
    if ((BIO_read(bio, certs, pending_bytes)) < pending_bytes) {
        free(certs);
        goto cleanup;
    }
    certs[pending_bytes] = '\0';

  cleanup:
    BIO_set_close(bio, BIO_CLOSE);
    BIO_free(bio);

    return certs;
}
Ejemplo n.º 22
0
extern "C" int ssl_verify_wrapper(int preverify_ok, X509_STORE_CTX *ctx)
{
	unsigned long binding;
	X509 *cert;
	SSL *ssl;
	BUF_MEM *buf;
	BIO *out;
	int result;

	cert = X509_STORE_CTX_get_current_cert(ctx);
	ssl = (SSL*) X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
	binding = (unsigned long) SSL_get_ex_data(ssl, 0);

	out = BIO_new(BIO_s_mem());
	PEM_write_bio_X509(out, cert);
	BIO_write(out, "\0", 1);
	BIO_get_mem_ptr(out, &buf);

	ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject(binding));
	result = (cd->VerifySslPeer(buf->data) == true ? 1 : 0);
	BIO_free(out);

	return result;
}
Ejemplo n.º 23
0
static void print_stuff(BIO *bio, SSL *s, int full)
{
    X509 *peer=NULL;
    char *p;
    static const char *space="                ";
    char buf[BUFSIZ];
    STACK_OF(X509) *sk;
    STACK_OF(X509_NAME) *sk2;
    SSL_CIPHER *c;
    X509_NAME *xn;
    int j,i;
#ifndef OPENSSL_NO_COMP
    const COMP_METHOD *comp, *expansion;
#endif

    if (full)
    {
        int got_a_chain = 0;

        sk=SSL_get_peer_cert_chain(s);
        if (sk != NULL)
        {
            got_a_chain = 1; /* we don't have it for SSL2 (yet) */

            BIO_printf(bio,"---\nCertificate chain\n");
            for (i=0; i<sk_X509_num(sk); i++)
            {
                X509_NAME_oneline(X509_get_subject_name(
                                      sk_X509_value(sk,i)),buf,sizeof buf);
                BIO_printf(bio,"%2d s:%s\n",i,buf);
                X509_NAME_oneline(X509_get_issuer_name(
                                      sk_X509_value(sk,i)),buf,sizeof buf);
                BIO_printf(bio,"   i:%s\n",buf);
                if (c_showcerts)
                    PEM_write_bio_X509(bio,sk_X509_value(sk,i));
            }
        }

        BIO_printf(bio,"---\n");
        peer=SSL_get_peer_certificate(s);
        if (peer != NULL)
        {
            BIO_printf(bio,"Server certificate\n");
            if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */
                PEM_write_bio_X509(bio,peer);
            X509_NAME_oneline(X509_get_subject_name(peer),
                              buf,sizeof buf);
            BIO_printf(bio,"subject=%s\n",buf);
            X509_NAME_oneline(X509_get_issuer_name(peer),
                              buf,sizeof buf);
            BIO_printf(bio,"issuer=%s\n",buf);
        }
        else
            BIO_printf(bio,"no peer certificate available\n");

        sk2=SSL_get_client_CA_list(s);
        if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0))
        {
            BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
            for (i=0; i<sk_X509_NAME_num(sk2); i++)
            {
                xn=sk_X509_NAME_value(sk2,i);
                X509_NAME_oneline(xn,buf,sizeof(buf));
                BIO_write(bio,buf,strlen(buf));
                BIO_write(bio,"\n",1);
            }
        }
        else
        {
            BIO_printf(bio,"---\nNo client certificate CA names sent\n");
        }
        p=SSL_get_shared_ciphers(s,buf,sizeof buf);
        if (p != NULL)
        {
            /* This works only for SSL 2.  In later protocol
             * versions, the client does not know what other
             * ciphers (in addition to the one to be used
             * in the current connection) the server supports. */

            BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n");
            j=i=0;
            while (*p)
            {
                if (*p == ':')
                {
                    BIO_write(bio,space,15-j%25);
                    i++;
                    j=0;
                    BIO_write(bio,((i%3)?" ":"\n"),1);
                }
                else
                {
                    BIO_write(bio,p,1);
                    j++;
                }
                p++;
            }
            BIO_write(bio,"\n",1);
        }

        BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
                   BIO_number_read(SSL_get_rbio(s)),
                   BIO_number_written(SSL_get_wbio(s)));
    }
    BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, "));
    c=SSL_get_current_cipher(s);
    BIO_printf(bio,"%s, Cipher is %s\n",
               SSL_CIPHER_get_version(c),
               SSL_CIPHER_get_name(c));
    if (peer != NULL) {
        EVP_PKEY *pktmp;
        pktmp = X509_get_pubkey(peer);
        BIO_printf(bio,"Server public key is %d bit\n",
                   EVP_PKEY_bits(pktmp));
        EVP_PKEY_free(pktmp);
    }
#ifndef OPENSSL_NO_COMP
    comp=SSL_get_current_compression(s);
    expansion=SSL_get_current_expansion(s);
    BIO_printf(bio,"Compression: %s\n",
               comp ? SSL_COMP_get_name(comp) : "NONE");
    BIO_printf(bio,"Expansion: %s\n",
               expansion ? SSL_COMP_get_name(expansion) : "NONE");
#endif
    SSL_SESSION_print(bio,SSL_get_session(s));
    BIO_printf(bio,"---\n");
    if (peer != NULL)
        X509_free(peer);
    /* flush, or debugging output gets mixed with http response */
    (void)BIO_flush(bio);
}
Ejemplo n.º 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);
	}
Ejemplo n.º 25
0
int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname,
                           int port)
{
	int match;
	int index;
	char* common_name = NULL;
	int common_name_length = 0;
	char** alt_names = NULL;
	int alt_names_count = 0;
	int* alt_names_lengths = NULL;
	BOOL certificate_status;
	BOOL hostname_match = FALSE;
	BOOL verification_status = FALSE;
	rdpCertificateData* certificate_data;

	if (tls->settings->ExternalCertificateManagement)
	{
		BIO* bio;
		int status;
		int length;
		int offset;
		BYTE* pemCert;
		freerdp* instance = (freerdp*) tls->settings->instance;
		/**
		 * Don't manage certificates internally, leave it up entirely to the external client implementation
		 */
		bio = BIO_new(BIO_s_mem());

		if (!bio)
		{
			WLog_ERR(TAG, "BIO_new() failure");
			return -1;
		}

		status = PEM_write_bio_X509(bio, cert->px509);

		if (status < 0)
		{
			WLog_ERR(TAG, "PEM_write_bio_X509 failure: %d", status);
			return -1;
		}

		offset = 0;
		length = 2048;
		pemCert = (BYTE*) malloc(length + 1);

		if (!pemCert)
		{
			WLog_ERR(TAG, "error allocating pemCert");
			return -1;
		}

		status = BIO_read(bio, pemCert, length);

		if (status < 0)
		{
			WLog_ERR(TAG, "failed to read certificate");
			return -1;
		}

		offset += status;

		while (offset >= length)
		{
			int new_len;
			BYTE* new_cert;
			new_len = length * 2;
			new_cert = (BYTE*) realloc(pemCert, new_len + 1);

			if (!new_cert)
				return -1;

			length = new_len;
			pemCert = new_cert;
			status = BIO_read(bio, &pemCert[offset], length);

			if (status < 0)
				break;

			offset += status;
		}

		if (status < 0)
		{
			WLog_ERR(TAG, "failed to read certificate");
			return -1;
		}

		length = offset;
		pemCert[length] = '\0';
		status = -1;

		if (instance->VerifyX509Certificate)
			status = instance->VerifyX509Certificate(instance, pemCert, length, hostname,
			         port, tls->isGatewayTransport);
		else
			WLog_ERR(TAG, "No VerifyX509Certificate callback registered!");

		free(pemCert);
		BIO_free(bio);

		if (status < 0)
		{
			WLog_ERR(TAG, "VerifyX509Certificate failed: (length = %d) status: [%d] %s",
			         length, status, pemCert);
			return -1;
		}

		return (status == 0) ? 0 : 1;
	}

	/* ignore certificate verification if user explicitly required it (discouraged) */
	if (tls->settings->IgnoreCertificate)
		return 1;  /* success! */

	/* if user explicitly specified a certificate name, use it instead of the hostname */
	if (tls->settings->CertificateName)
		hostname = tls->settings->CertificateName;

	/* attempt verification using OpenSSL and the ~/.freerdp/certs certificate store */
	certificate_status = x509_verify_certificate(cert,
	                     tls->certificate_store->path);
	/* verify certificate name match */
	certificate_data = crypto_get_certificate_data(cert->px509, hostname, port);
	/* extra common name and alternative names */
	common_name = crypto_cert_subject_common_name(cert->px509, &common_name_length);
	alt_names = crypto_cert_subject_alt_name(cert->px509, &alt_names_count,
	            &alt_names_lengths);

	/* compare against common name */

	if (common_name)
	{
		if (tls_match_hostname(common_name, common_name_length, hostname))
			hostname_match = TRUE;
	}

	/* compare against alternative names */

	if (alt_names)
	{
		for (index = 0; index < alt_names_count; index++)
		{
			if (tls_match_hostname(alt_names[index], alt_names_lengths[index], hostname))
			{
				hostname_match = TRUE;
				break;
			}
		}
	}

	/* if the certificate is valid and the certificate name matches, verification succeeds */
	if (certificate_status && hostname_match)
		verification_status = TRUE; /* success! */

	/* verification could not succeed with OpenSSL, use known_hosts file and prompt user for manual verification */
	if (!certificate_status || !hostname_match)
	{
		char* issuer;
		char* subject;
		char* fingerprint;
		freerdp* instance = (freerdp*) tls->settings->instance;
		DWORD accept_certificate = 0;
		issuer = crypto_cert_issuer(cert->px509);
		subject = crypto_cert_subject(cert->px509);
		fingerprint = crypto_cert_fingerprint(cert->px509);
		/* search for matching entry in known_hosts file */
		match = certificate_data_match(tls->certificate_store, certificate_data);

		if (match == 1)
		{
			/* no entry was found in known_hosts file, prompt user for manual verification */
			if (!hostname_match)
				tls_print_certificate_name_mismatch_error(
				    hostname, port,
				    common_name, alt_names,
				    alt_names_count);

			/* Automatically accept certificate on first use */
			if (tls->settings->AutoAcceptCertificate)
			{
				WLog_INFO(TAG, "No certificate stored, automatically accepting.");
				accept_certificate = 1;
			}
			else if (instance->VerifyCertificate)
			{
				accept_certificate = instance->VerifyCertificate(
				                         instance, common_name,
				                         subject, issuer,
				                         fingerprint, !hostname_match);
			}

			switch (accept_certificate)
			{
				case 1:
					/* user accepted certificate, add entry in known_hosts file */
					verification_status = certificate_data_print(tls->certificate_store,
					                      certificate_data);
					break;

				case 2:
					/* user did accept temporaty, do not add to known hosts file */
					verification_status = TRUE;
					break;

				default:
					/* user did not accept, abort and do not add entry in known_hosts file */
					verification_status = FALSE; /* failure! */
					break;
			}
		}
		else if (match == -1)
		{
			char* old_subject = NULL;
			char* old_issuer = NULL;
			char* old_fingerprint = NULL;
			/* entry was found in known_hosts file, but fingerprint does not match. ask user to use it */
			tls_print_certificate_error(hostname, port, fingerprint,
			                            tls->certificate_store->file);

			if (!certificate_get_stored_data(tls->certificate_store,
			                                 certificate_data, &old_subject,
			                                 &old_issuer, &old_fingerprint))
				WLog_WARN(TAG, "Failed to get certificate entry for %s:%d",
				          hostname, port);

			if (instance->VerifyChangedCertificate)
			{
				accept_certificate = instance->VerifyChangedCertificate(
				                         instance, common_name, subject, issuer,
				                         fingerprint, old_subject, old_issuer,
				                         old_fingerprint);
			}

			free(old_subject);
			free(old_issuer);
			free(old_fingerprint);

			switch (accept_certificate)
			{
				case 1:
					/* user accepted certificate, add entry in known_hosts file */
					verification_status = certificate_data_replace(tls->certificate_store,
					                      certificate_data);
					break;

				case 2:
					/* user did accept temporaty, do not add to known hosts file */
					verification_status = TRUE;
					break;

				default:
					/* user did not accept, abort and do not add entry in known_hosts file */
					verification_status = FALSE; /* failure! */
					break;
			}
		}
		else if (match == 0)
			verification_status = TRUE; /* success! */

		free(issuer);
		free(subject);
		free(fingerprint);
	}

	certificate_data_free(certificate_data);
	free(common_name);

	if (alt_names)
		crypto_cert_subject_alt_name_free(alt_names_count, alt_names_lengths,
		                                  alt_names);

	return (verification_status == 0) ? 0 : 1;
}
Ejemplo n.º 26
0
int MAIN(int argc, char **argv)
	{
	SSL_SESSION *x=NULL;
	int ret=1,i,num,badops=0;
	BIO *out=NULL;
	int informat,outformat;
	char *infile=NULL,*outfile=NULL,*context=NULL;
	int cert=0,noout=0,text=0;
	char **pp;

	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);

	informat=FORMAT_PEM;
	outformat=FORMAT_PEM;

	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,"-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,"-text") == 0)
			text= ++num;
		else if (strcmp(*argv,"-cert") == 0)
			cert= ++num;
		else if (strcmp(*argv,"-noout") == 0)
			noout= ++num;
		else if (strcmp(*argv,"-context") == 0)
		    {
		    if(--argc < 1) goto bad;
		    context=*++argv;
		    }
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badops=1;
			break;
			}
		argc--;
		argv++;
		}

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

	ERR_load_crypto_strings();
	x=load_sess_id(infile,informat);
	if (x == NULL) { goto end; }

	if(context)
	    {
	    x->sid_ctx_length=strlen(context);
	    if(x->sid_ctx_length > SSL_MAX_SID_CTX_LENGTH)
		{
		BIO_printf(bio_err,"Context too long\n");
		goto end;
		}
	    memcpy(x->sid_ctx,context,x->sid_ctx_length);
	    }

#ifdef undef
	/* just testing for memory leaks :-) */
	{
	SSL_SESSION *s;
	char buf[1024*10],*p;
	int i;

	s=SSL_SESSION_new();

	p= &buf;
	i=i2d_SSL_SESSION(x,&p);
	p= &buf;
	d2i_SSL_SESSION(&s,&p,(long)i);
	p= &buf;
	d2i_SSL_SESSION(&s,&p,(long)i);
	p= &buf;
	d2i_SSL_SESSION(&s,&p,(long)i);
	SSL_SESSION_free(s);
	}
#endif

	if (!noout || text)
		{
		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 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 (text)
		{
		SSL_SESSION_print(out,x);

		if (cert)
			{
			if (x->peer == NULL)
				BIO_puts(out,"No certificate present\n");
			else
				X509_print(out,x->peer);
			}
		}

	if (!noout && !cert)
		{
		if 	(outformat == FORMAT_ASN1)
			i=(int)i2d_SSL_SESSION_bio(out,x);
		else if (outformat == FORMAT_PEM)
			i=PEM_write_bio_SSL_SESSION(out,x);
		else	{
			BIO_printf(bio_err,"bad output format specified for outfile\n");
			goto end;
			}
		if (!i) {
			BIO_printf(bio_err,"unable to write SSL_SESSION\n");
			goto end;
			}
		}
	else if (!noout && (x->peer != NULL)) /* just print the certificate */
		{
		if 	(outformat == FORMAT_ASN1)
			i=(int)i2d_X509_bio(out,x->peer);
		else if (outformat == FORMAT_PEM)
			i=PEM_write_bio_X509(out,x->peer);
		else	{
			BIO_printf(bio_err,"bad output format specified for outfile\n");
			goto end;
			}
		if (!i) {
			BIO_printf(bio_err,"unable to write X509\n");
			goto end;
			}
		}
	ret=0;
end:
	if (out != NULL) BIO_free_all(out);
	if (x != NULL) SSL_SESSION_free(x);
	EXIT(ret);
	}
Ejemplo n.º 27
0
static void https_add_ssl_entries(connection *con) {
	X509 *xs;
	X509_NAME *xn;
	X509_NAME_ENTRY *xe;
	int i, nentries;

	if (
		SSL_get_verify_result(con->ssl) != X509_V_OK
		|| !(xs = SSL_get_peer_certificate(con->ssl))
	) {
		return;
	}

	xn = X509_get_subject_name(xs);
	for (i = 0, nentries = X509_NAME_entry_count(xn); i < nentries; ++i) {
		int xobjnid;
		const char * xobjsn;
		data_string *envds;

		if (!(xe = X509_NAME_get_entry(xn, i))) {
			continue;
		}
		xobjnid = OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe));
		xobjsn = OBJ_nid2sn(xobjnid);
		if (!xobjsn) {
			continue;
		}

		if (NULL == (envds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
			envds = data_string_init();
		}
		buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
		buffer_append_string(envds->key, xobjsn);
		buffer_copy_string_len(
			envds->value,
			(const char *)xe->value->data, xe->value->length
		);
		/* pick one of the exported values as "authed user", for example
		 * ssl.verifyclient.username   = "******" or "SSL_CLIENT_S_DN_emailAddress"
		 */
		if (buffer_is_equal(con->conf.ssl_verifyclient_username, envds->key)) {
			buffer_copy_string_buffer(con->authed_user, envds->value);
		}
		array_insert_unique(con->environment, (data_unset *)envds);
	}
	if (con->conf.ssl_verifyclient_export_cert) {
		BIO *bio;
		if (NULL != (bio = BIO_new(BIO_s_mem()))) {
			data_string *envds;
			int n;

			PEM_write_bio_X509(bio, xs);
			n = BIO_pending(bio);

			if (NULL == (envds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
				envds = data_string_init();
			}

			buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_CERT"));
			buffer_prepare_copy(envds->value, n+1);
			BIO_read(bio, envds->value->ptr, n);
			BIO_free(bio);
			envds->value->ptr[n] = '\0';
			envds->value->used = n+1;
			array_insert_unique(con->environment, (data_unset *)envds);
		}
	}
	X509_free(xs);
}
Ejemplo n.º 28
0
DDS_ReturnCode_t sp_extract_pem (DDS_Credentials *cred,
				 unsigned char  **cert,
				 size_t         *cert_len,
				 unsigned char  **key,
				 size_t         *key_len)
{
	BIO *cert_in, *key_in;
	int i;
	FILE *fp;
	long lSize;

	if (cred->credentialKind == DDS_ENGINE_BASED) {
		/* Not implemented */
	}
	else if (cred->credentialKind == DDS_FILE_BASED) {
		/* Read the certificate pem file */
		fp = fopen ( cred->info.filenames.certificate_chain_file , "rb" );
		if( !fp ) perror ( cred->info.filenames.certificate_chain_file),exit(1);
		
		fseek ( fp , 0L , SEEK_END);
		lSize = ftell( fp );
		rewind ( fp );
		
		*cert = calloc ( 1, lSize+1 );
		if( !*cert ) fclose(fp),fputs("memory alloc fails",stderr),exit(1);
		
		if( 1!=fread( (void *) *cert , lSize, 1 , fp) )
			fclose(fp),free(*cert),fputs("entire read fails",stderr),exit(1);
		
		*cert_len = (size_t) lSize;
		fclose(fp);

		/* Read private key pem file */
		fp = fopen (cred->info.filenames.private_key_file, "rb" );
		if (!fp) {
			perror (cred->info.filenames.private_key_file);
			exit(1);
		}
		
		fseek ( fp , 0L , SEEK_END);
		lSize = ftell( fp );
		rewind ( fp );
		
		*key = calloc ( 1, lSize+1 );
		if( !*key ) fclose(fp),fputs("memory alloc fails",stderr),exit(1);
		
		if( 1!=fread( (void *) *key , lSize, 1 , fp) )
			fclose(fp),free(*key),fputs("entire read fails",stderr),exit(1);
		
		*key_len = (size_t) lSize;
		fclose(fp);

	}
	else if (cred->credentialKind == DDS_SSL_BASED) {
		cert_in = BIO_new (BIO_s_mem ());
		key_in = BIO_new (BIO_s_mem ());
		
		/* Write the X509 to a PEM format in a BIO */
		for (i = 0; i < sk_X509_num (cred->info.sslData.certificate_list); i++)
			PEM_write_bio_X509(cert_in, sk_X509_value (cred->info.sslData.certificate_list, i));

		*cert = malloc (sizeof (unsigned char) * cert_in->num_write + 1);
		
		/* read from the BIO into a char * */
		*cert_len = BIO_read (cert_in, *cert, cert_in->num_write);
		memset (&(*cert) [(int) *cert_len], '\0', sizeof (char));

		/* Write the X509 to a PEM format in a BIO */
		PEM_write_bio_PrivateKey(key_in, cred->info.sslData.private_key, NULL, NULL, 0, 0, NULL);
		*key = malloc (sizeof (unsigned char) * key_in->num_write + 1);
		
		/* read from the BIO into a char * */
		*key_len = BIO_read (key_in, *key, key_in->num_write);
		memset (&(*key) [(int) *key_len], '\0', sizeof (char));
		BIO_free (cert_in);
		BIO_free (key_in);
	}
	else if (cred->credentialKind == DDS_DATA_BASED) {
		if (cred->info.data.private_key.format == DDS_FORMAT_PEM) {
			*key = malloc (sizeof (unsigned char) * cred->info.data.private_key.length + 1);
			strcpy ((char *) *key, (char *) cred->info.data.private_key.data);
			*key_len = cred->info.data.private_key.length;
		}
		else {
			/* Not implemented */
		}
		/* This is okay for the current useage, but not for the intended useage */
		for (i = 0; i < (int) cred->info.data.num_certificates ; i++) {
			if (cred->info.data.certificates [i].format == DDS_FORMAT_PEM) {
				*cert = malloc (sizeof (unsigned char) * cred->info.data.certificates [i].length + 1);
				strcpy ((char *) *cert, (char *) cred->info.data.certificates [i].data);
				*cert_len = cred->info.data.certificates [i].length;
			}
		}
	}
	else {
		/*TODO: Go get the cert from data*/
	}

	return (DDS_RETCODE_OK); 
}
Ejemplo n.º 29
0
DVT_STATUS CERTIFICATE_CLASS::generateFiles(LOG_CLASS* logger_ptr,
											const char* signerCredentialsFile_ptr, 
											const char* credentialsPassword_ptr,
											const char* keyPassword_ptr,
											const char* keyFile_ptr, 
											const char* certificateFile_ptr)

//  DESCRIPTION     : Generate a certificate and key files from this class.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           : If signerCredentialsFile_ptr is NULL, a self signed 
//					: certificate will be generated.
//					:
//					: Returns:  MSG_OK, MSG_LIB_NOT_EXIST, MSG_FILE_NOT_EXIST, 
//					: MSG_ERROR, MSG_INVALID_PASSWORD 
//<<===========================================================================
{
	DVT_STATUS ret = MSG_ERROR;
	unsigned long err;
	OPENSSL_CLASS* openSsl_ptr;
	BIO* caBio_ptr = NULL;
	EVP_PKEY* caPrivateKey_ptr = NULL;
	X509* caCertificate_ptr = NULL;
	EVP_PKEY* key_ptr = NULL;
	X509* cert_ptr = NULL;
	X509_NAME* name_ptr;
	time_t effectiveTime;
	time_t expirationTime;
	EVP_PKEY* tmpKey_ptr;
	const EVP_MD *digest_ptr;
	BIO* pkBio_ptr = NULL;
	const EVP_CIPHER *cipher_ptr;
	BIO* certBio_ptr = NULL;

	// check for the existence of the OpenSSL DLLs
	openSsl_ptr = OPENSSL_CLASS::getInstance();
	if (openSsl_ptr == NULL)
	{
		return MSG_LIB_NOT_EXIST;
	}

	// clear the error queue
	ERR_clear_error();

	if (signerCredentialsFile_ptr != NULL)
	{
		// open the credentials file
		caBio_ptr = BIO_new(BIO_s_file_internal());
		if (caBio_ptr == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting up to read CA credentials file");
			goto end;
		}
		if (BIO_read_filename(caBio_ptr, signerCredentialsFile_ptr) <= 0)
		{
			err = ERR_peek_error();
			if ((ERR_GET_LIB(err) == ERR_LIB_SYS) && (ERR_GET_REASON(err) == ERROR_FILE_NOT_FOUND))
			{
				// file does not exist
				ERR_clear_error(); // eat any errors
				ret = MSG_FILE_NOT_EXIST;
			}
			else
			{
				openSsl_ptr->printError(logger_ptr, LOG_ERROR, "opening CA credentials file for reading");
			}
			goto end;
		}

		// read the certificate authority's private key
		caPrivateKey_ptr = PEM_read_bio_PrivateKey(caBio_ptr, NULL, NULL, (void*)credentialsPassword_ptr);
		if (caPrivateKey_ptr == NULL)
		{
			err = ERR_peek_error();
			if ((ERR_GET_LIB(err) == ERR_LIB_EVP) && (ERR_GET_REASON(err) == EVP_R_BAD_DECRYPT))
			{
				// bad password
				ERR_clear_error(); // eat any errors
				ret = MSG_INVALID_PASSWORD;
			}
			else
			{
				openSsl_ptr->printError(logger_ptr, LOG_ERROR, "reading private key from CA credentials file");
			}
			goto end;
		}

		// read the certificate authority's certificate
		caCertificate_ptr = PEM_read_bio_X509(caBio_ptr, NULL, NULL, (void*)credentialsPassword_ptr);
		if (caCertificate_ptr == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "reading CA certificate from CA credentials file");
			goto end;
		}
	}

	// generate the new private/public key pair
	if (signatureAlgorithmM.compare("RSA") == 0)
	{
		// RSA key
		RSA* rsa_key;

		rsa_key = RSA_generate_key(signatureKeyLengthM, RSA_3, NULL, 0);
		if (rsa_key == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "generating RSA key");
			goto end;
		}

		key_ptr = EVP_PKEY_new();
		if (key_ptr == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "creating RSA key");
			RSA_free(rsa_key);
			goto end;
		}

		EVP_PKEY_assign_RSA(key_ptr, rsa_key);
	}
	else
	{
		// DSA key
		DSA* dsa_key;

		dsa_key = DSA_generate_parameters(signatureKeyLengthM, NULL, 0, NULL, NULL, NULL, 0);
		if (dsa_key == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "generating DSA parameters");
			goto end;
		}

		if (DSA_generate_key(dsa_key) == 0)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "generating DSA key");
			DSA_free(dsa_key);
			goto end;
		}

		key_ptr = EVP_PKEY_new();
		if (key_ptr == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "creating DSA key");
			DSA_free(dsa_key);
			goto end;
		}

		EVP_PKEY_assign_DSA(key_ptr, dsa_key);
	}

	// create the certificate
	cert_ptr = X509_new();
	if (cert_ptr == NULL)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "creating certificate object");
		goto end;
	}

	// version
	if (X509_set_version(cert_ptr, (versionM - 1)) != 1)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting certificate version");
		goto end;
	}

	// subject
	name_ptr = openSsl_ptr->onelineName2Name(subjectM.c_str());
	if (name_ptr == NULL)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "parsing owner name");
		goto end;
	}

	if (X509_set_subject_name(cert_ptr, name_ptr) != 1)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting owner name in certificate");
		goto end;
	}

	// issuer
	if (signerCredentialsFile_ptr != NULL)
	{
		// CA signed
		name_ptr = X509_get_subject_name(caCertificate_ptr);
		if (name_ptr == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "getting name from CA certificate");
			goto end;
		}

		if (X509_set_issuer_name(cert_ptr, name_ptr) != 1)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting issuer name in certificate");
			goto end;
		}
	}
	else
	{
		// self signed
		name_ptr = X509_NAME_dup(name_ptr); // duplicate the name so it can be used again
		if (name_ptr == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "duplicating owner name");
			goto end;
		}

		if (X509_set_issuer_name(cert_ptr, name_ptr) != 1)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting issuer name in certificate");
			goto end;
		}
	}
	
	// public key
	if (X509_set_pubkey(cert_ptr, key_ptr) != 1)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting public key in certificate");
		goto end;
	}

	// valid dates
	effectiveTime = mktime(&effectiveDateM);
	expirationTime = mktime(&expirationDateM);
	if ((X509_time_adj(X509_get_notBefore(cert_ptr), 0, &effectiveTime) == NULL) ||
		(X509_time_adj(X509_get_notAfter(cert_ptr), 0, &expirationTime) == NULL))
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting valid dates in certificate");
		goto end;
	}

	// serial number, use the current time_t
	ASN1_INTEGER_set(X509_get_serialNumber(cert_ptr), (unsigned)time(NULL));

	// sign the certificate
	if (signerCredentialsFile_ptr != NULL)
	{
		// CA signed
		tmpKey_ptr = caPrivateKey_ptr;
	}
	else
	{
		// self signed
		tmpKey_ptr = key_ptr;
	}

	if (EVP_PKEY_type(tmpKey_ptr->type) == EVP_PKEY_RSA)
	{
		digest_ptr = EVP_sha1();
	}
	else if (EVP_PKEY_type(tmpKey_ptr->type) == EVP_PKEY_DSA)
	{
		digest_ptr = EVP_dss1();
	}
	else
	{
		if (logger_ptr)
		{
			logger_ptr->text(LOG_ERROR, 1, "Unsupported key type in CA private key");
		}
		goto end;
	}

	if (!X509_sign(cert_ptr, tmpKey_ptr, digest_ptr))
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "signing certificate");
		goto end;
	}

	// write out the private key
	// open the private key file
	pkBio_ptr = BIO_new(BIO_s_file_internal());
	if (pkBio_ptr == NULL)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting up to write private key file");
		goto end;
	}
	if (BIO_write_filename(pkBio_ptr, (void *)keyFile_ptr) <= 0)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "opening to write private key file");
		goto end;
	}

	if ((keyPassword_ptr != NULL) && (strlen(keyPassword_ptr) > 0))
	{
		// we have a password, use 3DES to encrypt the key
		cipher_ptr = EVP_des_ede3_cbc();
	}
	else
	{
		// there is no password, don't encrypt the key
		cipher_ptr = NULL;
	}

	// write out the private key
	if (PEM_write_bio_PKCS8PrivateKey(pkBio_ptr, key_ptr, cipher_ptr, 
										NULL, 0, NULL, (void *)keyPassword_ptr) != 1)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing private key");
		goto end;
	}

	// write the certificate file
	// open the certificate file
	certBio_ptr = BIO_new(BIO_s_file_internal());
	if (certBio_ptr == NULL)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting up to write certificate file");
		goto end;
	}
	if (BIO_write_filename(certBio_ptr, (void *)certificateFile_ptr) <= 0)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "opening to write certificate file");
		goto end;
	}

	// write the new certificate
	if (PEM_write_bio_X509(certBio_ptr, cert_ptr) != 1)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing certificate");
		goto end;
	}

	// write the new certificate into the credential file 
	if (PEM_write_bio_X509(pkBio_ptr, cert_ptr) != 1)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing certificate");
		goto end;
	}


	if (signerCredentialsFile_ptr != NULL)
	{
		// write the CA certificate
		if (PEM_write_bio_X509(certBio_ptr, caCertificate_ptr) != 1)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing CA certificate");
			goto end;
		}

		// loop reading certificates from the CA credentials file and writing them to the certificate file
		X509_free(caCertificate_ptr);
		while ((caCertificate_ptr = PEM_read_bio_X509(caBio_ptr, NULL, NULL, (void*)credentialsPassword_ptr)) != NULL)
		{
			// write the certificate
			if (PEM_write_bio_X509(certBio_ptr, caCertificate_ptr) != 1)
			{
				openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing certificate chain");
				goto end;
			}

			X509_free(caCertificate_ptr);
		}
		// check the error
		err = ERR_peek_error();
		if ((ERR_GET_LIB(err) == ERR_LIB_PEM) && (ERR_GET_REASON(err) == PEM_R_NO_START_LINE))
		{
			// end of data - this is normal
			ERR_clear_error();
		}
		else
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "reading certificates from CA credentials file");
			goto end;
		}
	}


	ret = MSG_OK;

end:
	if (certBio_ptr != NULL) BIO_free(certBio_ptr);
	if (pkBio_ptr != NULL) BIO_free(pkBio_ptr);
	if (cert_ptr != NULL) X509_free(cert_ptr);
	if (key_ptr != NULL) EVP_PKEY_free(key_ptr);
	if (caCertificate_ptr != NULL) X509_free(caCertificate_ptr);
	if (caPrivateKey_ptr != NULL) EVP_PKEY_free(caPrivateKey_ptr);
	if (caBio_ptr != NULL) BIO_free(caBio_ptr);

	return ret;
}
Ejemplo n.º 30
0
static BOOL tls_extract_pem(CryptoCert cert, BYTE** PublicKey, DWORD* PublicKeyLength)
{
	BIO* bio;
	int status;
	size_t offset;
	int length = 0;
	BOOL rc = FALSE;
	BYTE* pemCert = NULL;

	if (!PublicKey || !PublicKeyLength)
		return FALSE;

	*PublicKey = NULL;
	*PublicKeyLength = 0;
	/**
	 * Don't manage certificates internally, leave it up entirely to the external client implementation
	 */
	bio = BIO_new(BIO_s_mem());

	if (!bio)
	{
		WLog_ERR(TAG, "BIO_new() failure");
		return FALSE;
	}

	status = PEM_write_bio_X509(bio, cert->px509);

	if (status < 0)
	{
		WLog_ERR(TAG, "PEM_write_bio_X509 failure: %d", status);
		goto fail;
	}

	offset = 0;
	length = 2048;
	pemCert = (BYTE*) malloc(length + 1);

	if (!pemCert)
	{
		WLog_ERR(TAG, "error allocating pemCert");
		goto fail;
	}

	status = BIO_read(bio, pemCert, length);

	if (status < 0)
	{
		WLog_ERR(TAG, "failed to read certificate");
		goto fail;
	}

	offset += status;

	while (offset >= length)
	{
		int new_len;
		BYTE* new_cert;
		new_len = length * 2;
		new_cert = (BYTE*) realloc(pemCert, new_len + 1);

		if (!new_cert)
			goto fail;

		length = new_len;
		pemCert = new_cert;
		status = BIO_read(bio, &pemCert[offset], length - offset);

		if (status < 0)
			break;

		offset += status;
	}

	if (status < 0)
	{
		WLog_ERR(TAG, "failed to read certificate");
		goto fail;
	}

	length = offset;
	pemCert[length] = '\0';
	*PublicKey = pemCert;
	*PublicKeyLength = length;
	rc = TRUE;
fail:

	if (!rc)
		free(pemCert);

	BIO_free(bio);
	return rc;
}