### Example: obtaining SSL object from X509_STORE_CTX to call SSL_set_retry_verify() Source: https://docs.openssl.org/master/man3/SSL_set_retry_verify Shows how to get the SSL object from the X509_STORE_CTX using SSL_get_ex_data_X509_STORE_CTX_idx() and X509_STORE_CTX_get_ex_data(), then call SSL_set_retry_verify() when retry is needed. Includes a check for invalid index. ```c int idx = SSL_get_ex_data_X509_STORE_CTX_idx(); SSL *ssl; /* this should not happen but check anyway */ if (idx < 0 || (ssl = X509_STORE_CTX_get_ex_data(ctx, idx)) == NULL) return 0; if (/* we need to retry verification callback */) return SSL_set_retry_verify(ssl); /* do normal processing of the verification callback */ ``` -------------------------------- ### BIO_s_fd - Hello World example Source: https://docs.openssl.org/master/man3/BIO_s_fd Example of creating a file descriptor BIO for stdout and printing a message. ```c BIO *out; out = BIO_new_fd(fileno(stdout), BIO_NOCLOSE); BIO_printf(out, "Hello World\n"); BIO_free(out); ``` -------------------------------- ### DANE Authentication Setup and Verification Example Source: https://docs.openssl.org/master/man3/SSL_CTX_dane_enable This example sets up DANE authentication for an SMTP client. It enables DANE on the SSL context and SSL object, adds TLSA records, and configures verification. It handles both usable and unusable TLSA records, and after the handshake, it checks verification results and prints DANE details. Note that the code contains placeholder comments for error handling and TLSA record iteration. ```c SSL_CTX *ctx; SSL *ssl; int (*verify_cb)(int ok, X509_STORE_CTX *sctx) = NULL; int num_usable = 0; const char *nexthop_domain = "example.com"; const char *dane_tlsa_domain = "smtp.example.com"; uint8_t usage, selector, mtype; if ((ctx = SSL_CTX_new(TLS_client_method())) == NULL) /* error */ if (SSL_CTX_dane_enable(ctx) <= 0) /* error */ if ((ssl = SSL_new(ctx)) == NULL) /* error */ if (SSL_dane_enable(ssl, dane_tlsa_domain) <= 0) /* error */ /* * For many applications it is safe to skip DANE-EE(3) namechecks. Do not * disable the checks unless "unknown key share" attacks pose no risk for * your application. */ SSL_dane_set_flags(ssl, DANE_FLAG_NO_DANE_EE_NAMECHECKS); if (!SSL_add1_dnsname(ssl, nexthop_domain)) /* error */ SSL_set_hostflags(ssl, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); for (... each TLSA record ...) { unsigned char *data; size_t len; int ret; /* set usage, selector, mtype, data, len */ /* * Opportunistic DANE TLS clients support only DANE-TA(2) or DANE-EE(3). * They treat all other certificate usages, and in particular PKIX-TA(0) * and PKIX-EE(1), as unusable. */ switch (usage) { default: case 0: /* PKIX-TA(0) */ case 1: /* PKIX-EE(1) */ continue; case 2: /* DANE-TA(2) */ case 3: /* DANE-EE(3) */ break; } ret = SSL_dane_tlsa_add(ssl, usage, selector, mtype, data, len); /* free data as appropriate */ if (ret < 0) /* handle SSL library internal error */ else if (ret == 0) /* handle unusable TLSA record */ else ++num_usable; } /* * At this point, the verification mode is still the default SSL_VERIFY_NONE. * Opportunistic DANE clients use unauthenticated TLS when all TLSA records * are unusable, so continue the handshake even if authentication fails. */ if (num_usable == 0) { /* Log all records unusable? */ /* Optionally set verify_cb to a suitable non-NULL callback. */ SSL_set_verify(ssl, SSL_VERIFY_NONE, verify_cb); } else { /* At least one usable record. We expect to verify the peer */ /* Optionally set verify_cb to a suitable non-NULL callback. */ /* * Below we elect to fail the handshake when peer verification fails. * Alternatively, use the permissive SSL_VERIFY_NONE verification mode, * complete the handshake, check the verification status, and if not * verified disconnect gracefully at the application layer, especially if * application protocol supports informing the server that authentication * failed. */ SSL_set_verify(ssl, SSL_VERIFY_PEER, verify_cb); } /* * Load any saved session for resumption, making sure that the previous * session applied the same security and authentication requirements that * would be expected of a fresh connection. */ /* Perform SSL_connect() handshake and handle errors here */ if (SSL_session_reused(ssl)) { if (SSL_get_verify_result(ssl) == X509_V_OK) { /* * Resumed session was originally verified, this connection is * authenticated. */ } else { /* * Resumed session was not originally verified, this connection is not * authenticated. */ } } else if (SSL_get_verify_result(ssl) == X509_V_OK) { const char *peername = SSL_get0_peername(ssl); EVP_PKEY *mspki = NULL; int depth = SSL_get0_dane_authority(ssl, NULL, &mspki); if (depth >= 0) { (void) SSL_get0_dane_tlsa(ssl, &usage, &selector, &mtype, NULL, NULL); printf("DANE TLSA %d %d %d ", usage, selector, mtype); if (SSL_get0_peer_rpk(ssl) == NULL) printf("%s certificate at depth %d\n", (mspki != NULL) ? "signed the peer" : mdpth ? "matched the TA" : "matched the EE", mdpth); else printf(bio, "matched the peer raw public key\n"); } if (peername != NULL) { /* Name checks were in scope and matched the peername */ printf("Verified peername: %s\n", peername); } } else { /* * Not authenticated, presumably all TLSA rrs unusable, but possibly a * callback suppressed connection termination despite the presence of * usable TLSA RRs none of which matched. Do whatever is appropriate for * fresh unauthenticated connections. */ } ``` -------------------------------- ### Generic STORE retrieval example Source: https://docs.openssl.org/master/man7/ossl_store Example demonstrating how to open a STORE, iterate over objects, and close the STORE. It shows using OSSL_STORE_open, OSSL_STORE_eof, OSSL_STORE_load, OSSL_STORE_INFO_get_type, OSSL_STORE_INFO_get0_CERT, and OSSL_STORE_close. ```APIDOC ## Generic STORE retrieval example ### Description This example demonstrates the typical pattern of opening a STORE, retrieving objects one at a time, and closing the STORE. It shows how to handle an OSSL_STORE_INFO object, specifically for certificates. ### Functions Used - `OSSL_STORE_open` - `OSSL_STORE_eof` - `OSSL_STORE_load` - `OSSL_STORE_INFO_get_type` - `OSSL_STORE_INFO_get0_CERT` - `OSSL_STORE_INFO_free` - `OSSL_STORE_close` ### Example Code ```c #include /* for UI_get_default_method */ #include OSSL_STORE_CTX *ctx = OSSL_STORE_open("file:/foo/bar/data.pem", UI_get_default_method(), NULL, NULL, NULL); /* * OSSL_STORE_eof() simulates file semantics for any repository to signal * that no more data can be expected */ while (!OSSL_STORE_eof(ctx)) { OSSL_STORE_INFO *info = OSSL_STORE_load(ctx); /* * Do whatever is necessary with the OSSL_STORE_INFO, * here just one example */ switch (OSSL_STORE_INFO_get_type(info)) { case OSSL_STORE_INFO_CERT: /* Print the X.509 certificate text */ X509_print_fp(stdout, OSSL_STORE_INFO_get0_CERT(info)); /* Print the X.509 certificate PEM output */ PEM_write_X509(stdout, OSSL_STORE_INFO_get0_CERT(info)); break; } OSSL_STORE_INFO_free(info); } OSSL_STORE_close(ctx); ``` ``` -------------------------------- ### Example: Connecting to a Web Server Source: https://docs.openssl.org/master/man3/BIO_s_connect Example code demonstrating how to use BIO_new_connect, BIO_do_connect, and BIO_read/BIO_write to connect to a web server and retrieve a page. ```APIDOC ## Example: Connecting to a Web Server ### Description This example connects to a webserver on the local host and attempts to retrieve a page and copy the result to standard output. ### Code ```c BIO *cbio, *out; int len; char tmpbuf[1024]; cbio = BIO_new_connect("localhost:http"); out = BIO_new_fp(stdout, BIO_NOCLOSE); if (BIO_do_connect(cbio) <= 0) { fprintf(stderr, "Error connecting to server\n"); ERR_print_errors_fp(stderr); exit(1); } BIO_puts(cbio, "GET / HTTP/1.0\n\n"); for (;;) { len = BIO_read(cbio, tmpbuf, 1024); if (len <= 0) break; BIO_write(out, tmpbuf, len); } BIO_free(cbio); BIO_free(out); ``` ``` -------------------------------- ### SSL_set_srp_server_param and SRP server setup Source: https://docs.openssl.org/master/man3/SSL_CTX_set_srp_password Setup SRP server parameters using a verifier file and a callback function. ```APIDOC ## SSL_set_srp_server_param and SRP server setup ### Description Configure the SRP server parameters using a verifier file and a callback that supplies the SRP parameters for a given username. ### Functions - `int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, const BIGNUM *s, const BIGNUM *v, const char *info)` - `void SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg)` - `void SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, int (*cb)(SSL *s, int *ad, void *arg))` - `char *SSL_get_srp_username(SSL *s)` ### Parameters - `s` (SSL*) - Required - The SSL connection. - `N`, `g`, `s`, `v` (BIGNUM*) - Required - SRP parameters (prime, generator, salt, verifier). - `info` (const char*) - Optional - Additional info. - `ctx` (SSL_CTX*) - Required - The SSL context. - `arg` (void*) - Required - User data passed to the callback. - `cb` (function pointer) - Required - Callback to set SRP server parameters. ### Return Values - `SSL_set_srp_server_param()` returns 1 on success and -1 on failure. - `SSL_get_srp_username()` returns a pointer to the requested data; memory is owned by the library and should not be freed by the caller. ### Example ```c #include #include const char *srpvfile = "password.srpv"; int srpServerCallback(SSL *s, int *ad, void *arg) { SRP_VBASE *srpData = (SRP_VBASE*) arg; char *username = SSL_get_srp_username(s); SRP_user_pwd *user_pwd = SRP_VBASE_get1_by_user(srpData, username); if (!user_pwd) /* Error */ return SSL3_AL_FATAL; if (SSL_set_srp_server_param(s, user_pwd->N, user_pwd->g, user_pwd->s, user_pwd->v, user_pwd->info) < 0) /* Error */ SRP_user_pwd_free(user_pwd); return SSL_ERROR_NONE; } SSL_CTX *ctx = SSL_CTX_new(TLS_server_method()); if (!ctx) /* Error */ /* * seedKey should contain a NUL terminated sequence * of random non NUL bytes */ const char *seedKey; SRP_VBASE *srpData = SRP_VBASE_new(seedKey); if (SRP_VBASE_init(srpData, (char*) srpvfile) != SRP_NO_ERROR) /* Error */ SSL_CTX_set_srp_cb_arg(ctx, srpData); SSL_CTX_set_srp_username_callback(ctx, srpServerCallback); ``` ``` -------------------------------- ### Example config file for asn1parse Source: https://docs.openssl.org/master/man1/openssl-asn1parse Example configuration file used with -genconf. Defines a SEQUENCE with a BOOL and a UTF8String field. ```text asn1=SEQUENCE:seq_sect [seq_sect] field1=BOOL:TRUE field2=EXP:0, UTF8:some random string ``` -------------------------------- ### Example: Decapsulate data using RSA Source: https://docs.openssl.org/master/man3/EVP_PKEY_decapsulate Example code demonstrating how to use EVP_PKEY_decapsulate_init and EVP_PKEY_decapsulate to decapsulate data using an RSA private key. ```APIDOC ## Example: Decapsulate data using RSA ### Description This example shows how to initialize a decapsulation context with an RSA private key, set the KEM operation mode, determine the required buffer length, and perform the decapsulation. ### Code ```c #include /* * NB: assumes rsa_priv_key is an RSA private key, * and that in, inlen are already set up to contain encapsulated data. */ EVP_PKEY_CTX *ctx = NULL; size_t secretlen = 0; unsigned char *secret = NULL;; ctx = EVP_PKEY_CTX_new_from_pkey(libctx, rsa_priv_key, NULL); if (ctx == NULL) /* Error */ if (EVP_PKEY_decapsulate_init(ctx, NULL) <= 0) /* Error */ /* Set the mode - only 'RSASVE' is currently supported */ if (EVP_PKEY_CTX_set_kem_op(ctx, "RSASVE") <= 0) /* Error */ /* Determine buffer length */ if (EVP_PKEY_decapsulate(ctx, NULL, &secretlen, in, inlen) <= 0) /* Error */ secret = OPENSSL_malloc(secretlen); if (secret == NULL) /* malloc failure */ /* Decapsulated secret data is secretlen bytes long */ if (EVP_PKEY_decapsulate(ctx, secret, &secretlen, in, inlen) <= 0) /* Error */ ``` ``` -------------------------------- ### Start s_server to accept web browser connections Source: https://docs.openssl.org/master/man1/openssl-s_server Use this command to start an SSL server that accepts connections from a web browser on port 443 with the -www option. This is useful for debugging SSL clients. ```bash openssl s_server -accept 443 -www ``` -------------------------------- ### HKDF Key Derivation Example Source: https://docs.openssl.org/master/man3/EVP_PKEY_CTX_set_hkdf_md Example demonstrating how to derive key material using the EVP_PKEY HKDF interface with SHA-256, including setting the message digest, salt, key, and info parameters. ```APIDOC ## EVP_PKEY_CTX_set_hkdf_md ### Description Sets the message digest for the HKDF key derivation. This function is part of the OpenSSL EVP_PKEY HKDF API. ### Method C function ### Parameters - **pctx** (EVP_PKEY_CTX *) - Required - The key derivation context. - **md** (const EVP_MD *) - Required - The message digest to use (e.g., EVP_sha256()). ### Returns - **int** - Returns 1 on success, 0 or a negative value on failure. ### Example ```c EVP_PKEY_CTX *pctx; unsigned char out[10]; size_t outlen = sizeof(out); pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); if (EVP_PKEY_derive_init(pctx) <= 0) /* Error */ if (EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()) <= 0) /* Error */ if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, "salt", 4) <= 0) /* Error */ if (EVP_PKEY_CTX_set1_hkdf_key(pctx, "secret", 6) <= 0) /* Error */ if (EVP_PKEY_CTX_add1_hkdf_info(pctx, "label", 5) <= 0) /* Error */ if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) /* Error */ ``` ### Conforming To RFC 5869 ### See Also EVP_PKEY_CTX_new(3), EVP_PKEY_CTX_ctrl_str(3), EVP_PKEY_derive(3) ### History All of the functions described here were converted from macros to functions in OpenSSL 3.0. ``` -------------------------------- ### OBJ_create Source: https://docs.openssl.org/master/man3/OBJ_nid2obj Creates a new NID and initializes an object from it. The example shows creating a new NID and then using OBJ_nid2obj to get the object. ```APIDOC ## OBJ_create ### Description Creates a new NID and initializes an object from it. The example shows creating a new NID and then using OBJ_nid2obj to get the object. ### Example ```c int new_nid = OBJ_create("1.2.3.4", "NewOID", "New Object Identifier"); ASN1_OBJECT *obj = OBJ_nid2obj(new_nid); ``` ``` -------------------------------- ### Example: Create a core BIO and write data Source: https://docs.openssl.org/master/man3/BIO_s_core Shows how to create a core BIO using BIO_new_from_core_bio() and write to it with BIO_puts(). Returns 0 on failure, 1 on success. ```c int some_function(OSSL_LIB_CTX *libctx, OSSL_CORE_BIO *corebio) { BIO *cbio = BIO_new_from_core_bio(libctx, corebio); if (cbio == NULL) return 0; BIO_puts(cbio, "Hello World\n"); BIO_free(cbio); return 1; } ``` -------------------------------- ### Generate and store an 8192-bit password verifier Source: https://docs.openssl.org/master/man3/SRP_create_verifier Example from the EXAMPLES section showing how to generate and store an 8192-bit password verifier using SRP_create_verifier_BN_ex(). Error handling is omitted for clarity. It creates an SRP_VBASE, gets the default group parameters for 8192 bits, generates a salt and verifier, and adds the user to the SRP_VBASE. ```c #include #include const char *username = "username"; const char *password = "password"; SRP_VBASE *srpData = SRP_VBASE_new(NULL); SRP_gN *gN = SRP_get_default_gN("8192"); BIGNUM *salt = NULL, *verifier = NULL; SRP_create_verifier_BN_ex(username, password, &salt, &verifier, gN->N, gN->g, NULL, NULL); SRP_user_pwd *pwd = SRP_user_pwd_new(); SRP_user_pwd_set1_ids(pwd, username, NULL); SRP_user_pwd_set0_sv(pwd, salt, verifier); SRP_user_pwd_set_gN(pwd, gN->g, gN->N); SRP_VBASE_add0_user(srpData, pwd); ``` -------------------------------- ### X509_STORE_CTX_init() Source: https://docs.openssl.org/master/man3/X509_STORE_CTX_new Initializes an existing X509_STORE_CTX structure. Returns 1 on success or 0 on error. ```APIDOC ## X509_STORE_CTX_init() ### Description Initializes an X509_STORE_CTX structure. ### Returns - **int** - 1 for success, 0 if an error occurred. ``` -------------------------------- ### OpenSSL library configuration file example Source: https://docs.openssl.org/master/man5/config Shows the default section with config_diagnostics and openssl_conf, and the initialization section with placeholders for OID, providers, EVP properties, SSL/TLS, and random configurations. ```ini # These must be in the default section config_diagnostics = 1 openssl_conf = openssl_init [openssl_init] oid_section = oids providers = providers alg_section = evp_properties ssl_conf = ssl_configuration random = random [oids] ... new oids here ... [providers] ... provider stuff here ... [evp_properties] ... EVP properties here ... [ssl_configuration] ... SSL/TLS configuration properties here ... [random] ... random properties here ... ``` -------------------------------- ### verify_callback example with ex_data and depth limit Source: https://docs.openssl.org/master/man3/SSL_CTX_set_verify A complete example of a custom verify_callback for a server that allows but does not require client certificates. It prints all verification errors, optionally prints certificate chain information, enforces a depth limit by setting the error to X509_V_ERR_CERT_CHAIN_TOO_LONG, and can always continue the handshake. It uses ex_data to store and retrieve application data (mydata_t) from the SSL structure. The example includes setup calls to SSL_get_ex_new_index, SSL_CTX_set_verify, SSL_CTX_set_verify_depth, SSL_set_ex_data, and SSL_accept. ```c ... typedef struct { int verbose_mode; int verify_depth; int always_continue; } mydata_t; int mydata_index; ... static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { char buf[256]; X509 *err_cert; int err, depth; SSL *ssl; mydata_t *mydata; err_cert = X509_STORE_CTX_get_current_cert(ctx); err = X509_STORE_CTX_get_error(ctx); depth = X509_STORE_CTX_get_error_depth(ctx); /* * Retrieve the pointer to the SSL of the connection currently treated * and the application specific data stored into the SSL object. */ ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); mydata = SSL_get_ex_data(ssl, mydata_index); X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); /* * Catch a too long certificate chain. The depth limit set using * SSL_CTX_set_verify_depth() is by purpose set to "limit+1" so * that whenever the "depth>verify_depth" condition is met, we * have violated the limit and want to log this error condition. * We must do it here, because the CHAIN_TOO_LONG error would not * be found explicitly; only errors introduced by cutting off the * additional certificates would be logged. */ if (depth > mydata->verify_depth) { preverify_ok = 0; err = X509_V_ERR_CERT_CHAIN_TOO_LONG; X509_STORE_CTX_set_error(ctx, err); } if (!preverify_ok) { printf("verify error:num=%d:%s:depth=%d:%s\n", err, X509_verify_cert_error_string(err), depth, buf); } else if (mydata->verbose_mode) { printf("depth=%d:%s\n", depth, buf); } /* * At this point, err contains the last verification error. We can use * it for something special */ if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) { X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, 256); printf("issuer= %s\n", buf); } if (mydata->always_continue) return 1; else return preverify_ok; } ... mydata_t mydata; ... mydata_index = SSL_get_ex_new_index(0, "mydata index", NULL, NULL, NULL); ... SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_callback); /* * Let the verify_callback catch the verify_depth error so that we get * an appropriate error in the logfile. */ SSL_CTX_set_verify_depth(verify_depth + 1); /* * Set up the SSL specific data into "mydata" and store it into th SSL * structure. */ mydata.verify_depth = verify_depth; ... SSL_set_ex_data(ssl, mydata_index, &mydata); ... SSL_accept(ssl); /* check of success left out for clarity */ if (peer = SSL_get_peer_certificate(ssl)) { if (SSL_get_verify_result(ssl) == X509_V_OK) { /* The client sent a certificate which verified OK */ } } ``` -------------------------------- ### Example 1: Setting Parameters Source: https://docs.openssl.org/master/man3/OSSL_PARAM Shows how to construct an OSSL_PARAM array to set parameters on an object. ```APIDOC ## Example 1: Setting Parameters ### Description This example demonstrates how to set up an OSSL_PARAM array for setting parameters on some object. ### Code ```c #include const char *foo = "some string"; size_t foo_l = strlen(foo); const char bar[] = "some other string"; OSSL_PARAM set[] = { { "foo", OSSL_PARAM_UTF8_PTR, &foo, foo_l, 0 }, { "bar", OSSL_PARAM_UTF8_STRING, (void *)&bar, sizeof(bar) - 1, 0 }, { NULL, 0, NULL, 0, 0 } }; ``` ``` -------------------------------- ### BIO_f_md() digest chain with BIO_write() example Source: https://docs.openssl.org/master/man3/BIO_f_md Creates a BIO chain with SHA1 and MD5 digest BIOs and writes "Hello World" through it. 'bio' is the start of the chain, 'mdtmp' can be discarded after pushing. Error checking omitted. ```c BIO *bio, *mdtmp; char message[] = "Hello World"; bio = BIO_new(BIO_s_null()); mdtmp = BIO_new(BIO_f_md()); BIO_set_md(mdtmp, EVP_sha1()); /* * For BIO_push() we want to append the sink BIO and keep a note of * the start of the chain. */ bio = BIO_push(mdtmp, bio); mdtmp = BIO_new(BIO_f_md()); BIO_set_md(mdtmp, EVP_md5()); zio = BIO_push(mdtmp, bio); /* Note: mdtmp can now be discarded */ BIO_write(bio, message, strlen(message)); ``` -------------------------------- ### Replace BN_CTX_init with BN_CTX_new Source: https://docs.openssl.org/master/man3/BN_CTX_new Example showing how to replace BN_CTX_init with BN_CTX_new. Check the return value for NULL and free the context with BN_CTX_free. ```c BN_CTX *ctx; ctx = BN_CTX_new(); if (!ctx) /* error */ ... BN_CTX_free(ctx); ``` -------------------------------- ### Send HTTP request with SSL_write_ex Source: https://docs.openssl.org/master/man7/ossl-guide-tls-client-block Writes an HTTP GET request in three parts: start, hostname, and end. SSL_write_ex returns 1 on success and 0 on failure; on failure the code prints an error and jumps to the end label. ```c size_t written; const char *request_start = "GET / HTTP/1.1\r\nConnection: close\r\nHost: "; const char *request_end = "\r\n\r\n"; /* Write an HTTP GET request to the peer */ if (!SSL_write_ex(ssl, request_start, strlen(request_start), &written)) { printf("Failed to write start of HTTP request\n"); goto end; } if (!SSL_write_ex(ssl, hostname, strlen(hostname), &written)) { printf("Failed to write hostname in HTTP request\n"); goto end; } if (!SSL_write_ex(ssl, request_end, strlen(request_end), &written)) { printf("Failed to write end of HTTP request\n"); goto end; } ``` -------------------------------- ### EVP_PKEY_verify_init_ex Source: https://docs.openssl.org/master/man3/EVP_PKEY_verify Same as EVP_PKEY_verify_init but additionally sets the provided parameters on the context before returning. ```APIDOC ## EVP_PKEY_verify_init_ex ### Description Same as EVP_PKEY_verify_init() but additionally sets the passed parameters on the context before returning. ### Syntax ```c int EVP_PKEY_verify_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]); ``` ### Parameters - **ctx** (EVP_PKEY_CTX *) - Required - The public key algorithm context to initialize. - **params** (const OSSL_PARAM[]) - Required - Parameters to set on the context. ### Return Value Returns 1 for success and 0 or a negative value for failure. ``` -------------------------------- ### SSL/TLS Client Example using BIO_new_ssl_connect Source: https://docs.openssl.org/master/man3/BIO_f_ssl Connects to an HTTPS server, sends a GET request, and prints the response. Uses BIO_new_ssl_connect, BIO_do_connect, and BIO_read. Requires seeding the PRNG and setting verify paths (marked with XXX comments). ```c BIO *sbio, *out; int len; char tmpbuf[1024]; SSL_CTX *ctx; SSL *ssl; /* XXX Seed the PRNG if needed. */ ctx = SSL_CTX_new(TLS_client_method()); /* XXX Set verify paths and mode here. */ sbio = BIO_new_ssl_connect(ctx); BIO_get_ssl(sbio, &ssl); if (ssl == NULL) { fprintf(stderr, "Can't locate SSL pointer\n"); ERR_print_errors_fp(stderr); exit(1); } /* XXX We might want to do other things with ssl here */ /* An empty host part means the loopback address */ BIO_set_conn_hostname(sbio, ":https"); out = BIO_new_fp(stdout, BIO_NOCLOSE); if (BIO_do_connect(sbio) <= 0) { fprintf(stderr, "Error connecting to server\n"); ERR_print_errors_fp(stderr); exit(1); } /* XXX Could examine ssl here to get connection info */ BIO_puts(sbio, "GET / HTTP/1.0\n\n"); for (;;) { len = BIO_read(sbio, tmpbuf, 1024); if (len <= 0) break; BIO_write(out, tmpbuf, len); } BIO_free_all(sbio); BIO_free(out); ``` -------------------------------- ### Safely initialize and use a lock with CRYPTO_THREAD_run_once Source: https://docs.openssl.org/master/man3/CRYPTO_THREAD_run_once This example shows how to safely initialize and use a CRYPTO_RWLOCK using CRYPTO_THREAD_run_once. It includes Windows header handling and demonstrates proper lock acquisition and release. Note that finalization of locks is not covered and the simplest solution is to leak the lock. ```c #ifdef _WIN32 # include #endif #include static CRYPTO_ONCE once = CRYPTO_ONCE_STATIC_INIT; static CRYPTO_RWLOCK *lock; static void myinit(void) { lock = CRYPTO_THREAD_lock_new(); } static int mylock(void) { if (!CRYPTO_THREAD_run_once(&once, void init) || lock == NULL) return 0; return CRYPTO_THREAD_write_lock(lock); } static int myunlock(void) { return CRYPTO_THREAD_unlock(lock); } int serialized(void) { int ret = 0; if (!mylock()) { /* Do not unlock unless the lock was successfully acquired. */ return 0; } /* Your code here, do not return without releasing the lock! */ ret = ... ; myunlock(); return ret; } ``` -------------------------------- ### X509_STORE_CTX_init_rpk() Source: https://docs.openssl.org/master/man3/X509_STORE_CTX_new Initializes an X509_STORE_CTX structure for raw public key (RPK) usage. Returns 1 on success or 0 on error. ```APIDOC ## X509_STORE_CTX_init_rpk() ### Description Initializes an X509_STORE_CTX structure for raw public key (RPK) usage. ### Returns - **int** - 1 for success, 0 if an error occurred. ``` -------------------------------- ### HKDF-SHA256 Algorithm example deriving 10 bytes Source: https://docs.openssl.org/master/man7/EVP_KDF-HKDF Derives 10 bytes using the HKDF-SHA256 algorithm with secret key "secret", salt "salt", and info "label". Uses the same OSSL_PARAM setup as the generic HKDF example but without specifying a digest, since the algorithm already implies SHA-256. On failure, calls error("EVP_KDF_derive"). ```c EVP_KDF *kdf; EVP_KDF_CTX *kctx; unsigned char out[10]; OSSL_PARAM params[4], *p = params; kdf = EVP_KDF_fetch(NULL, "HKDF-SHA256", NULL); kctx = EVP_KDF_CTX_new(kdf); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, "secret", (size_t)6); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, "label", (size_t)5); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, "salt", (size_t)4); *p = OSSL_PARAM_construct_end(); if (EVP_KDF_derive(kctx, out, sizeof(out), params) <= 0) { error("EVP_KDF_derive"); } EVP_KDF_CTX_free(kctx); ``` -------------------------------- ### RSA encryption with OAEP padding using EVP_PKEY_encrypt Source: https://docs.openssl.org/master/man3/EVP_PKEY_encrypt Example of encrypting data with an RSA public key using OAEP padding. Assumes key, in, and inlen are already set up. Demonstrates context creation, initialization, padding setup, buffer length determination, and encryption. ```c #include #include EVP_PKEY_CTX *ctx; unsigned char *out, *in; size_t outlen, inlen; EVP_PKEY *key; /* * NB: assumes key, in, inlen are already set up, * and that key is an RSA public key */ ctx = EVP_PKEY_CTX_new_from_pkey(NULL, key, NULL); if (!ctx) /* Error occurred */ if (EVP_PKEY_encrypt_init(ctx) <= 0) /* Error */ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) /* Error */ /* Determine buffer length */ if (EVP_PKEY_encrypt(ctx, NULL, &outlen, in, inlen) <= 0) /* Error */ out = OPENSSL_malloc(outlen); if (!out) /* malloc failure */ if (EVP_PKEY_encrypt(ctx, out, &outlen, in, inlen) <= 0) /* Error */ /* Encrypted data is outlen bytes written to buffer out */ ``` -------------------------------- ### Typical output of openssl asn1parse Source: https://docs.openssl.org/master/man1/openssl-asn1parse Shows the typical output format of the asn1parse command. Each line starts with the offset in decimal, d=XX specifies the current depth, hl=XX gives the header length, and l=XX gives the length of the contents octets. This example is part of a self-signed certificate. ```text 0:d=0 hl=4 l= 681 cons: SEQUENCE ``` ```text 229:d=3 hl=3 l= 141 prim: BIT STRING 373:d=2 hl=3 l= 162 cons: cont [ 3 ] 376:d=3 hl=3 l= 159 cons: SEQUENCE 379:d=4 hl=2 l= 29 cons: SEQUENCE 381:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Subject Key Identifier 386:d=5 hl=2 l= 22 prim: OCTET STRING 410:d=4 hl=2 l= 112 cons: SEQUENCE 412:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Authority Key Identifier 417:d=5 hl=2 l= 105 prim: OCTET STRING 524:d=4 hl=2 l= 12 cons: SEQUENCE ``` -------------------------------- ### Predefined key variables for RSA examples Source: https://docs.openssl.org/master/man3/OSSL_PARAM_BLD Declares the BIGNUM and unsigned int variables used by both RSA examples. These variables are assumed to be predefined before the example code. ```c BIGNUM *n; /* modulus */ unsigned int e; /* public exponent */ BIGNUM *d; /* private exponent */ BIGNUM *p, *q; /* first two prime factors */ BIGNUM *dmp1, *dmq1; /* first two CRT exponents */ BIGNUM *iqmp; /* first CRT coefficient */ ``` -------------------------------- ### Obtain IKEV2KDF context Source: https://docs.openssl.org/master/man7/EVP_KDF-IKEV2KDF Shows how to fetch the IKEV2KDF algorithm and create a new context. This is the standard setup before any IKEV2KDF operation. ```c EVP_KDF *kdf = EVP_KDF_fetch(NULL, "IKEV2KDF", NULL); EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); ``` -------------------------------- ### noCheck example Source: https://docs.openssl.org/master/man5/x509v3_config Example of the OCSP No Check extension. It is parsed but ignored. ```openssl-config noCheck = ignored ``` -------------------------------- ### EVP_PKEY_sign_init_ex Source: https://docs.openssl.org/master/man3/EVP_PKEY_sign Same as EVP_PKEY_sign_init() but with additional parameters set on the context. ```APIDOC ## EVP_PKEY_sign_init_ex ### Description Same as EVP_PKEY_sign_init() but additionally sets the passed parameters on the context before returning. ### Syntax ```c int EVP_PKEY_sign_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]); ``` ### Parameters - **ctx** (EVP_PKEY_CTX *) - Required - The context to initialize for signing. - **params** (const OSSL_PARAM[]) - Optional - Parameters to set on the context. ### Return Value Returns 1 for success and 0 or a negative value for failure. ``` -------------------------------- ### inhibitAnyPolicy example Source: https://docs.openssl.org/master/man5/x509v3_config Example of the inhibitAnyPolicy extension with a non-negative integer value. ```openssl-config inhibitAnyPolicy = 2 ``` -------------------------------- ### Obtain KRB5KDF context with EVP_KDF_fetch and EVP_KDF_CTX_new Source: https://docs.openssl.org/master/man7/EVP_KDF-KRB5KDF Shows how to create a KRB5KDF context by fetching the KDF implementation and creating a new context. This is the initial step before setting parameters and deriving keys. ```c EVP_KDF *kdf = EVP_KDF_fetch(NULL, "KRB5KDF", NULL); EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); ``` -------------------------------- ### Set up a CMP client context Source: https://docs.openssl.org/master/man3/OSSL_CMP_CTX_new Creates a new CMP context and configures the server connection and trusted certificates. Error handling is omitted. ```c cmp_ctx = OSSL_CMP_CTX_new(); OSSL_CMP_CTX_set1_server(cmp_ctx, name_or_address); OSSL_CMP_CTX_set1_serverPort(cmp_ctx, port_string); OSSL_CMP_CTX_set1_serverPath(cmp_ctx, path_or_alias); OSSL_CMP_CTX_set0_trusted(cmp_ctx, ts); ``` -------------------------------- ### policyConstraints example Source: https://docs.openssl.org/master/man5/x509v3_config Example of the policyConstraints extension using requireExplicitPolicy with a non-negative integer value. ```openssl-config policyConstraints = requireExplicitPolicy:3 ``` -------------------------------- ### OSSL_SELF_TEST_onbegin Source: https://docs.openssl.org/master/man3/OSSL_SELF_TEST_new Marks the start of a self test block and triggers the callback with phase 'Start'. ```APIDOC ## OSSL_SELF_TEST_onbegin ### Description May be inserted at the start of a block of self test code. It can be used for diagnostic purposes. If this method is called, the callback will receive an OSSL_PARAM object with the phase set to "Start". ### Syntax ```c void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type, const char *desc); ``` ### Parameters - **st** (OSSL_SELF_TEST*) - Required - The OSSL_SELF_TEST object. - **type** (const char*) - Required - The type of self test being run. - **desc** (const char*) - Required - The description of the self test. ### Callback Parameters When the callback is invoked, it receives the following OSSL_PARAM objects: - "st-phase" (OSSL_PROV_PARAM_SELF_TEST_PHASE) - UTF8 string - The value is "Start". - "st-type" (OSSL_PROV_PARAM_SELF_TEST_TYPE) - UTF8 string - The value is set by the _type_ parameter. - "st-desc" (OSSL_PROV_PARAM_SELF_TEST_DESC) - UTF8 string - The value is set by the _desc_ parameter. ### Return Value None. ``` -------------------------------- ### X509_STORE_CTX_init Source: https://docs.openssl.org/master/man3/X509_STORE_CTX_new Sets up an X509_STORE_CTX for a subsequent verification operation. Must be called before each verification call. ```APIDOC ## X509_STORE_CTX_init ### Description Sets up the X509_STORE_CTX for a subsequent verification operation. It initializes the internal state and resources, sets verification parameters associated with the method name `default` (including the `any` purpose), and takes over callback function pointers from the trust store (unless NULL). It must be called before each call to X509_verify_cert() or X509_STORE_CTX_verify(). The trusted certificate store is set to the given trust store, which may be NULL. The certificate to be verified is set to the target, and a list of additional untrusted certificates may be provided. The target certificate is not copied and must not be freed before verification is complete. ### Method Function ### Signature int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *trust_store, X509 *target, STACK_OF(X509) *untrusted); ### Parameters - **ctx** (X509_STORE_CTX*) - Required - The context to initialize. - **trust_store** (X509_STORE*) - Optional - The trusted certificate store. May be NULL. - **target** (X509*) - Optional - The certificate to be verified. May be NULL, but verification will need a target. - **untrusted** (STACK_OF(X509)*) - Optional - A list of additional untrusted certificates used to build the chain. May be NULL. ### Return Value Returns 1 on success or 0 on failure. ``` -------------------------------- ### tlsfeature example Source: https://docs.openssl.org/master/man5/x509v3_config Example of the TLS Feature (must staple) extension using the status_request identifier. ```openssl-config tlsfeature = status_request ``` -------------------------------- ### Full TEST-RAND usage example with parameters and generation Source: https://docs.openssl.org/master/man7/EVP_RAND-TEST-RAND Complete example that fetches the TEST-RAND implementation, creates a context, sets strength, test entropy, and test nonce parameters, instantiates the generator, and generates bytes. The entropy and nonce arrays are initialized with placeholder data; the generate parameter defaults to zero, so output is limited to the supplied entropy and nonce. ```c EVP_RAND *rand; EVP_RAND_CTX *rctx; unsigned char bytes[100]; OSSL_PARAM params[4], *p = params; unsigned char entropy[1000] = { ... }; unsigned char nonce[20] = { ... }; unsigned int strength = 48; rand = EVP_RAND_fetch(NULL, "TEST-RAND", NULL); rctx = EVP_RAND_CTX_new(rand, NULL); EVP_RAND_free(rand); *p++ = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, &strength); *p++ = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, entropy, sizeof(entropy)); *p++ = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_NONCE, nonce, sizeof(nonce)); *p = OSSL_PARAM_construct_end(); EVP_RAND_instantiate(rctx, strength, 0, NULL, 0, params); EVP_RAND_generate(rctx, bytes, sizeof(bytes), strength, 0, NULL, 0); EVP_RAND_CTX_free(rctx); ``` -------------------------------- ### EVP_PKEY_CTX_get0_libctx Source: https://docs.openssl.org/master/man3 Gets the library context from an EVP_PKEY_CTX. This is part of the functions for getting diverse information from an EVP_PKEY_CTX. ```APIDOC ## EVP_PKEY_CTX_get0_libctx ### Description Gets the library context from an EVP_PKEY_CTX. ### Function Signature `OSSL_LIB_CTX *EVP_PKEY_CTX_get0_libctx(EVP_PKEY_CTX *ctx);` ### Parameters - **ctx** (EVP_PKEY_CTX*) - Required - The key context. ### Return Value Returns the library context, or NULL on failure. ``` -------------------------------- ### Setup SRP server with verifier file Source: https://docs.openssl.org/master/man3/SSL_CTX_set_srp_password Shows how to set up an SRP server using a verifier file. The callback retrieves the user's SRP parameters and sets them on the SSL object. Returns SSL_ERROR_NONE on success. ```c #include #include const char *srpvfile = "password.srpv"; int srpServerCallback(SSL *s, int *ad, void *arg) { SRP_VBASE *srpData = (SRP_VBASE*) arg; char *username = SSL_get_srp_username(s); SRP_user_pwd *user_pwd = SRP_VBASE_get1_by_user(srpData, username); if (!user_pwd) /* Error */ return SSL3_AL_FATAL; if (SSL_set_srp_server_param(s, user_pwd->N, user_pwd->g, user_pwd->s, user_pwd->v, user_pwd->info) < 0) /* Error */ SRP_user_pwd_free(user_pwd); return SSL_ERROR_NONE; } SSL_CTX *ctx = SSL_CTX_new(TLS_server_method()); if (!ctx) /* Error */ /* * seedKey should contain a NUL terminated sequence * of random non NUL bytes */ const char *seedKey; SRP_VBASE *srpData = SRP_VBASE_new(seedKey); if (SRP_VBASE_init(srpData, (char*) srpvfile) != SRP_NO_ERROR) /* Error */ SSL_CTX_set_srp_cb_arg(ctx, srpData); SSL_CTX_set_srp_username_callback(ctx, srpServerCallback); ```