C OpenSSL: How to get X509_STORE_CTX from X509_STORE? - c

I have a X509_STORE* pointer, my goal is to get its associated X509_STORE_CTX* pointer. May I know how to do this? I cannot get access to where initialize the X509_STORE_CTX*.
probably this is a simple question, but I check the OpenSSL manual API and its related header file again and again, not find any API could do this. Thanks.

A single X509_STORE can be used/shared by an unlimited number of X509_STORE_CTX, but most of the time isn't used/referenced by any, so an API to get "its ... pointer" makes no sense and does not exist.
This (not at all coincidentally) reflects a similar, but inversely named, difference at the SSL module (libssl) level. An SSL_CTX object defines security parameters that can be used by any number of connections each implemented as an SSL object. In the original design, the SSL_CTX owns an X509_STORE representing the truststore -- the set of roots (or other anchors if PARTIAL_CHAIN is used) used to validate peer certs and potentially to build out 'own' chains -- which you can modify using the CTX APIs like SSL_CTX_load_verify_locations or you can get the (automatically created) store with SSL_CTX_get_cert_store and modify it or create your own and install it with SSL_CTX_set_cert_store. OTOH each SSL dynamically creates its own X509_STORE_CTX while validating or sending a cert; no X509_STORE_CTX exists at other times. In 1.0.2 up an SSL by default uses the SSL_CTX store but you can override with SSL_set[01]_{verify,chain}_cert_store.
When you create an X509_STORE_CTX you identify the X509_STORE to use with X509_STORE_CTX_init. When you _free it this use/reference is terminated.

Related

How to duplicate a SSL_CTX object in a TLS application?

I am having a application in. c that uses openssl for TLS v1.2 implemention.
The application shall open multiple remote connections to remote server running with the same version of TLS. I have a single set of key, certificate and CA_certificate to be used for all connections.
I need to maintain the SSL_CTX object for each client separately. But, I wish to create a single global SSL_CTX context object and configure it once for the following:
SSL_CTX_set_ecdh_auto()
SSL_CTX_use_certificate_file()
SL_CTX_use_PrivateKey_file()
SSL_CTX_set_verify()
SSL_CTX_set_options()
SSL_CTX_load_verify_locations
SSL_CTX_set_verify_depth()
And then, for each connections initiated by the application, I can duplicate (make a copy) of the above configured context ctx and call SSL_new() directly, without going through the listed steps over and over for each client.
Does Openssl provide any function to duplicate the SSL_CTX object?
If not is there any other safe way to do so? like memcpy() etc.
SSL_CTX has a counting reference. It means it will be freed when its reference counts reaches zero.
So rather than copying SSL_CTX, just increase its reference by SSL_CTX_up_ref() and use same object. As a result, your code will be something like this:
SSL_CTX *g_ssl_ctx = nullptr;
//...
//init g_ssl_ctx
//...
SSL_CTX *get_client_ctx() {
SSL_CTX_up_ref(g_ssl_ctx);
return g_ssl_ctx;
}

send_v3trap context value

I am developing shared library and subagent for net-snmp. I need to send v3 traps for specific hardware events. I would like to know what value need to be filled in the context value of send_v3trap API.
void send_v3trap(netsnmp_variable_list * vars,const char * context )
Is this context value, same as user defined engine id ? i.e., the one which needs to be configured in snmptrapd.conf as below ?
createUser -e ENGINEID myuser SHA "my authentication pass" AES "my encryption pass"
More on configuring in this link
There is an example source code available for sending
v2traps
By looking at the net-snmp source code, send_v3trap calls internally send_v2trap and eventually,
/* A context name was provided, so copy it and its length to the v2 pdu
* template. */
if (context != NULL)
{
template_v2pdu->contextName = strdup(context);
template_v2pdu->contextNameLen = strlen(context);
}
Answering my own question.
"context" value can be filled with
value returned by "snmpv3_get_engineID"
NULL
As long as, configurations are proper in terms of v3 i.e., trapsess -v3 specified in the host and on the target, engineid of net-snmp is specified, then everything works fine.
Only unclear part still is, if someone is able to send v3 traps without specifying "context", in which scenario would it be useful really !

How can I pass a socket between instances on App Engine using the Go runtime?

The Python runtime allows it by pickling the connection. Is there a similar way to share sockets using the Go runtime on classic App Engine with google.golang.org/appengine/socket?
The descriptor isn't exposed in the Go API: https://github.com/golang/appengine/blob/master/socket/socket_classic.go#L152
type Conn struct {
ctx context.Context
desc string
offset int64
prot pb.CreateSocketRequest_SocketProtocol
local, remote *pb.AddressPort
readDeadline, writeDeadline time.Time // optional
}
desc is what you would need on the other side to reconstruct the socket.
It should be possible fork this library on GitHub, change the conn struct to expose the needed desc property, and then change the import to github.com/YOURUSERNAME/appengine/socket instead of appengine/socket.
It's a lot of work so if you can come up with a different way to solve this you're probably better off. Nevertheless it should be possible.

CryptoApi: Export a certificate without the private key?

I have generated a self signed certificate using the CertCreateSelfSignCertificate function. This yields a PCCERT_CONTEXT.
How can I export the certificate stored in the PCCERT_CONTEXT variable with only the public key? I want to do this, to send it to other parties in the network, so these are able to encrypt messages using the public key.
I thought this was a straight forward option, but it isnt.
No need for a pfx.
The certificate is present inside the structure CERT_CONTEXT : just save the content of the buffer pointed by the member pbCertEncoded and whose length is the value of the member cbCertEncoded.
Moreover, the public key from this certificate is directly present in the CERT_CONTEXT structure : pCertInfo->SubjectPublicKeyInfo. For example, you can import it using CryptImportPublicKeyInfo and then call CryptEncrypt to encrypt data.
With these two options, you have all what is needed to start encrypting messages. Of course, the private key must be kept safe to be able to decrypt encrypted data.
Looks like you will need to first put the certificate into a certificate store and then export it using PFXExportCertStoreEx passing dwFlags of 0 (i.e. not setting EXPORT_PRIVATE_KEYS).
P.S. nothing is ever straight forward when dealing with cryptography libraries, be it CryptAPI, JSSE, OpenSSL... it's always a nightmare.

Openssl query about usage

I am trying to use OpenSSL in my application, and achieve a secure connection.
At first I tried:
create ssl struct
create socketbio for the tcp socket
create a sslbio
set socketbio to SSL strcut
SSL_accept(ssl)
BIO_push(ssl, socketbio)
This cause handshake to happen successfully, but application data wasn't properly decrypted.
Then I tweaked a little, and relaced 6 with
(new) BIO_ctrl(sslbio, SET_SSL, ssl)
and things worked fine.
I Wanted to know, what's wrong with previous approach, and what's causing the new apprach work?
It's hard to answer the question without knowing why you think BIO_push is all you need to do. At any rate, you shouldn't call BIO_ctrl directly. You should use the high-level wrapper BIO_set_ssl defined in bio.h:
#define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
This macro sets the ssl member of the BIO object as you can see in bio_ssl.c:
case BIO_C_SET_SSL:
if (ssl != NULL)
ssl_free(b);
b->shutdown=(int)num;
ssl=(SSL *)ptr;
((BIO_SSL *)b->ptr)->ssl=ssl;
bio=SSL_get_rbio(ssl);
if (bio != NULL)
{
if (b->next_bio != NULL)
BIO_push(bio,b->next_bio);
b->next_bio=bio;
CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO);
}
b->init=1;
break;
The important step in this function is not the BIO_push, but rather is where it sets the ssl pointer in the BIO_SSL object to your active SSL context, i.e., ((BIO_SSL *)b->ptr)->ssl=ssl;.

Resources