int _trust_this_cert (SSL_CTX * the_ctx, char *certspec) { netsnmp_cert *trustcert; DEBUGMSGTL (("sslctx_client", "Trying to load a trusted certificate: %s\n", certspec)); /* load this identifier into the trust chain */ trustcert = netsnmp_cert_find (NS_CERT_CA, NS_CERTKEY_MULTIPLE, certspec); if (!trustcert) trustcert = netsnmp_cert_find (NS_CERT_REMOTE_PEER, NS_CERTKEY_MULTIPLE, certspec); if (!trustcert) LOGANDDIE ("failed to find requested certificate to trust"); /* Add the certificate to the context */ if (netsnmp_cert_trust_ca (the_ctx, trustcert) != SNMPERR_SUCCESS) LOGANDDIE ("failed to load trust certificate"); return 1; }
SSL_CTX *_sslctx_common_setup (SSL_CTX * the_ctx, _netsnmpTLSBaseData * tlsbase) { char *crlFile; char *cipherList; X509_LOOKUP *lookup; X509_STORE *cert_store = NULL; _load_trusted_certs (the_ctx); /* add in the CRLs if available */ crlFile = netsnmp_ds_get_string (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_X509_CRL_FILE); if (NULL != crlFile) { cert_store = SSL_CTX_get_cert_store (the_ctx); DEBUGMSGTL (("sslctx_client", "loading CRL: %s\n", crlFile)); if (!cert_store) LOGANDDIE ("failed to find certificate store"); if (!(lookup = X509_STORE_add_lookup (cert_store, X509_LOOKUP_file ()))) LOGANDDIE ("failed to create a lookup function for the CRL file"); if (X509_load_crl_file (lookup, crlFile, X509_FILETYPE_PEM) != 1) LOGANDDIE ("failed to load the CRL file"); /* tell openssl to check CRLs */ X509_STORE_set_flags (cert_store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); } cipherList = netsnmp_ds_get_string (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_TLS_ALGORITMS); if (NULL != cipherList) { if (SSL_CTX_set_cipher_list (the_ctx, cipherList) != 1) LOGANDDIE ("failed to set the cipher list to the requested value"); else snmp_log (LOG_INFO, "set SSL cipher list to '%s'\n", cipherList); } return the_ctx; }
SSL_CTX * sslctx_server_setup(const SSL_METHOD *method) { netsnmp_cert *id_cert; /*********************************************************************** * Set up the server context */ /* setting up for ssl */ SSL_CTX *the_ctx = SSL_CTX_new(NETSNMP_REMOVE_CONST(SSL_METHOD *, method)); if (!the_ctx) { LOGANDDIE("can't create a new context"); } id_cert = netsnmp_cert_find(NS_CERT_IDENTITY, NS_CERTKEY_DEFAULT, NULL); if (!id_cert) LOGANDDIE ("error finding server identity keys"); if (!id_cert->key || !id_cert->key->okey) LOGANDDIE("failed to load private key"); DEBUGMSGTL(("sslctx_server", "using public key: %s\n", id_cert->info.filename)); DEBUGMSGTL(("sslctx_server", "using private key: %s\n", id_cert->key->info.filename)); if (SSL_CTX_use_certificate(the_ctx, id_cert->ocert) <= 0) LOGANDDIE("failed to set the certificate to use"); if (SSL_CTX_use_PrivateKey(the_ctx, id_cert->key->okey) <= 0) LOGANDDIE("failed to set the private key to use"); if (!SSL_CTX_check_private_key(the_ctx)) LOGANDDIE("public and private keys incompatible"); SSL_CTX_set_read_ahead(the_ctx, 1); /* XXX: DTLS only? */ SSL_CTX_set_verify(the_ctx, SSL_VERIFY_PEER| SSL_VERIFY_FAIL_IF_NO_PEER_CERT| SSL_VERIFY_CLIENT_ONCE, &verify_callback); return _sslctx_common_setup(the_ctx, NULL); }
SSL_CTX *sslctx_client_setup (const SSL_METHOD * method, _netsnmpTLSBaseData * tlsbase) { netsnmp_cert *id_cert, *peer_cert; SSL_CTX *the_ctx; /*********************************************************************** * Set up the client context */ the_ctx = SSL_CTX_new (NETSNMP_REMOVE_CONST (SSL_METHOD *, method)); if (!the_ctx) { snmp_log (LOG_ERR, "ack: %p\n", the_ctx); LOGANDDIE ("can't create a new context"); } SSL_CTX_set_read_ahead (the_ctx, 1); /* Required for DTLS */ SSL_CTX_set_verify (the_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, &verify_callback); if (tlsbase->our_identity) { DEBUGMSGTL (("sslctx_client", "looking for local id: %s\n", tlsbase->our_identity)); id_cert = netsnmp_cert_find (NS_CERT_IDENTITY, NS_CERTKEY_MULTIPLE, tlsbase->our_identity); } else { DEBUGMSGTL (("sslctx_client", "looking for default local id: %s\n", tlsbase->our_identity)); id_cert = netsnmp_cert_find (NS_CERT_IDENTITY, NS_CERTKEY_DEFAULT, NULL); } if (!id_cert) LOGANDDIE ("error finding client identity keys"); if (!id_cert->key || !id_cert->key->okey) LOGANDDIE ("failed to load private key"); DEBUGMSGTL (("sslctx_client", "using public key: %s\n", id_cert->info.filename)); DEBUGMSGTL (("sslctx_client", "using private key: %s\n", id_cert->key->info.filename)); if (SSL_CTX_use_certificate (the_ctx, id_cert->ocert) <= 0) LOGANDDIE ("failed to set the certificate to use"); if (SSL_CTX_use_PrivateKey (the_ctx, id_cert->key->okey) <= 0) LOGANDDIE ("failed to set the private key to use"); if (!SSL_CTX_check_private_key (the_ctx)) LOGANDDIE ("public and private keys incompatible"); if (tlsbase->their_identity) peer_cert = netsnmp_cert_find (NS_CERT_REMOTE_PEER, NS_CERTKEY_MULTIPLE, tlsbase->their_identity); else peer_cert = netsnmp_cert_find (NS_CERT_REMOTE_PEER, NS_CERTKEY_DEFAULT, NULL); if (peer_cert) { DEBUGMSGTL (("sslctx_client", "server's expected public key: %s\n", peer_cert ? peer_cert->info.filename : "none")); /* Trust the expected certificate */ if (netsnmp_cert_trust_ca (the_ctx, peer_cert) != SNMPERR_SUCCESS) LOGANDDIE ("failed to set verify paths"); } /* trust a certificate (possibly a CA) aspecifically passed in */ if (tlsbase->trust_cert) { if (!_trust_this_cert (the_ctx, tlsbase->trust_cert)) return 0; } return _sslctx_common_setup (the_ctx, tlsbase); }