5.1 Programming with SSL
从这一点上,我们将弥合差距到更高级的OpenSSL功能。 本章的目的是将图书馆的特征分成较小的群体,以建立一个过程的感觉。 我们希望这个过程可以作为开发者在自己的应用中实现SSL的模板。 在将SSL添加到应用程序中时,必须考虑应用程序的独特要求,并且必须对安全性和功能性做出最佳决策。
以下步骤为开发人员在实施SSL客户端或服务器时提供了一个模板。 我们将从一个小例子开始,并以此为基础。 直到所有的步骤都被认真考虑,这个例子对我们的满意是不安全的。 在每一步中,我们将介绍一小剂量的API; 在所有步骤之后,开发人员应该能够更清楚地思考启用SSL的应用程序的设计。 然而,完成这些步骤并不是路的尽头。 为了解决许多应用程序的需求,我们需要进一步研究API的高级功能。
5.1.2.1 Background
Function | Comments |
SSLv2_method | Returns a pointer to SSL_METHOD for generic SSL Version 2 |
SSLv2_client_method | Returns a pointer to SSL_METHOD for an SSL Version 2 client |
SSLv2_server_method | Returns a pointer to SSL_METHOD for an SSL Version 2 server |
SSLv3_method | Returns a pointer to SSL_METHOD for generic SSL Version 3 |
SSLv3_client_method | Returns a pointer to SSL_METHOD for an SSL Version 3 client |
SSLv3_server_method | Returns a pointer to SSL_METHOD for an SSL Version 3 server |
TLSv1_method | Returns a pointer to SSL_METHOD for generic TLS Version 1 |
TLSv1_client_method | Returns a pointer to SSL_METHOD for a TLS Version 1 client |
TLSv1_server_method | Returns a pointer to SSL_METHOD for a TLS Version 1 server |
SSLv23_method | Returns a pointer to SSL_METHOD for generic SSL/TLS |
SSLv23_client_method | Returns a pointer to SSL_METHOD for an SSL/TLS client |
SSLv23_server_method | Returns a pointer to SSL_METHOD for an SSL/TLS server |
通常,服务器应用程序应始终向对等方提供证书,客户端可以选择这样做。 应用程序的目的和期望的安全性应决定是否使用客户端证书。OpenSSL在握手期间向客户端提交客户端证书,只要我们为客户端分配证书,服务器请求客户端证书。
函数 | int passwd_cb(char * buf, int size, int flag, void *userdata); |
功能 | 回调函数的义务是将密码复制到调用时提供给它的缓冲区中。 回调函数用四个参数调用。 |
参数 | |
buf | 密码应该被复制到的缓冲区。 |
size | 缓冲区的大小(以字节为单位) |
flag | 通过为零或非零。 当该标志不为零时,该密码将用于执行加密; 否则,它将被用来执行解密。 |
userdata | 被SSL_CTX_set_default_passwd_cb_userdata使用 |
Generating the Files Needed by the Examples
a.To create the root CA:
$openssl req -newkey rsa:1024 -sha1 -keyout rootkey.pem -out rootreq.pem
$ openssl x509 -req -in rootreq.pem -sha1 -extfile myopenssl.cnf > -extensions v3_ca -signkey rootkey.pem -out rootcert.pem
$ cat rootcert.pem rootkey.pem > root.pem
$ openssl x509 -subject -issuer -noout -in root.pem
subject= /C=US/ST=VA/L=Fairfax/O=Zork.org/CN=Root CA
issuer= /C=US/ST=VA/L=Fairfax/O=Zork.org/CN=Root CA
b.To create the server CA and sign it with the root CA:
$ openssl req -newkey rsa:1024 -sha1 -keyout serverCAkey.pem -out > serverCAreq.pem
$ openssl x509 -req -in serverCAreq.pem -sha1 -extfile > myopenssl.cnf -extensions v3_ca -CA root.pem -CAkey root.pem > -CAcreateserial -out serverCAcert.pem
$ cat serverCAcert.pem serverCAkey.pem rootcert.pem > serverCA.pem
$ openssl x509 -subject -issuer -noout -in serverCA.pem
subject= /C=US/ST=VA/L=Fairfax/O=Zork.org/OU=Server
Division/CN=Server CA
issuer= /C=US/ST=VA/L=Fairfax/O=Zork.org/CN=Root CA
c.To create the server's certificate and sign it with the Server CA
$ openssl req -newkey rsa:1024 -sha1 -keyout serverkey.pem -out > serverreq.pem
$ openssl x509 -req -in serverreq.pem -sha1 -extfile myopenssl.cnf > -extensions usr_cert -CA serverCA.pem -CAkey serverCA.pem > -CAcreateserial -out servercert.pem
$ cat servercert.pem serverkey.pem serverCAcert.pem rootcert.pem > > server.pem
$ openssl x509 -subject -issuer -noout -in server.pem
subject= /C=US/ST=VA/L=Fairfax/O=Zork.org/CN=splat.zork.org
issuer= /C=US/ST=VA/L=Fairfax/O=Zork.org/OU=Server
Division/CN=Server CA
d.To create the client certificate and sign it with the Root CA
$ openssl req -newkey rsa:1024 -sha1 -keyout clientkey.pem -out > clientreq.pem
$ openssl x509 -req -in clientreq.pem -sha1 -extfile myopenssl.cnf > -extensions usr_cert -CA root.pem -CAkey root.pem > -CAcreateserial -out clientcert.pem
$ cat clientcert.pem clientkey.pem rootcert.pem > client.pem
$ openssl x509 -subject -issuer -noout -in client.pem
subject= /C=US/ST=VA/L=Fairfax/O=Zork.org/CN=shell.zork.org
issuer= /C=US/ST=VA/L=Fairfax/O=Zork.org/CN=Root CA
e.To create dh512.pem and dh1024.pem:
$ openssl dhparam -check -text -5 512 -out dh512.pem
$ openssl dhparam -check -text -5 1024 -out dh1024.pem
5.1.3 Step 2: Peer Authentication
启用SSL的程序的安全性由于未能正确验证对等证书而受到损害。 在这一步中,我们将研究处理可信证书,证书链验证,CRL使用和连接后验证的各种API调用。
函数 | int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,const char *CApath); |
功能 | 将可信任的CA证书加载到我们的应用程序中,作为附加设置 SSL_CTX对象。 |
参数 | |
ctx | 可信CA证书的SSL上下文对象将被加载到。 |
CAfile | 包含PEM格式的CA证书的文件的名称。 文件中可能存在多个CA证书。 |
CApath | 包含CA证书的目录的名称。 |
备注 | We can call SSL_CTX_load_verify_locations with either the second or the third arguments specified as NULL, but not both. |
下载CA证书使用
SSL_CTX_set_default_verify_paths和 SSL_CTX_load_verify_locations函数
5.1.3.3 Certificate verification
SSL_CTX_set_verify
参数 | 功能 |
SSL_VERIFY_NONE | 在服务器模式下使用上下文时,不会向客户端发送证书请求,客户端也不应发送证书。 |
SSL_VERIFY_PEER | 在服务器模式下使用上下文时,将向客户端发送证书请求。 |
SSL_VERIFY_FAIL_IF_NO_PEER_CERT | 如果上下文未在服务器模式下使用,或者SSL_VERIFY_PEER未设置,则忽略此标志。 |
SSL_VERIFY_CLIENT_ONCE | 如果上下文未在服务器模式下使用,或者SSL_VERIFY_PEER未设置,则忽略此标志。 |
X509_STORE *SSL_CTX_get_cert_store(SSL_CTX *ctx);
SSL_get_verify_result | 我们将在我们的连接后检查中使用。 |
SSL_get_peer_certificate | 函数SSL_get_peer_certificate将返回一个指向X509对象的指针 包含同行的证书 |
5.1.4 Step 3: SSL Options and Cipher Suites
SSL_CTX_set_options | SSL_CTX_set_options函数为开发人员提供了对从上下文产生的SSL连接的更好控制。 |
SSL_CTX_set_verify |
5.2.1 SSL Session Caching
SSL会话与SSL连接不同。 会话是指通过执行握手而创建的一组参数和加密密钥,而连接是使用会话的活动会话。 换言之,连接是指通信的过程,而会话是指通信所建立的参数。 了解这一点,我们可以深入研究一些提供SSL会话缓存的OpenSSL例程。
业务流程:
SSL_get_session |
SSL_get0_session |
SSL_get1_session |
PEM_write_bio_SSL_SESSION |
PEM_read_bio_SSL_SESSION |
SSL_set_session |
SSL_connect |
SSL_SESSION_free |
5.2.1.3 An on-disk, session caching framework
函数 | int new_session_cb(SSL *ctx, SSL_SESSION *session); |
功能 | 无论何时由SSL_CTX对象创建新的SSL_SESSION,都会调用由SSL_CTX_sess_set_new_cb设置的回调。... |
参数 | 意义 |
ctx | SSL连接的连接对象。 |
session | 新创建的会话对象 |
函数 | void remove_session_cb(SSL_CTX *ctx, SSL_SESSION *session); |
功能 | 破坏会话层对象 |
参数 | 意义 |
ctx | SSL连接的连接对象。 |
session | 新创建的会话对象 |
函数 | SSL_SESSION *get_session_cb(SSL *ctx, unsigned char *id, int len, int* ref); |
功能 | SSL_CTX_sess_set_get_cb函数用于设置缓存检索回调。 |
参数 | 意义 |
ctx | SSL连接的连接对象。 |
id | 对方请求的会话ID。 |
len | 会话ID的长度。 |
ref | 来自回调的输出。 |
Table 5-3. Some common return values of SSL_get_error | |
Return value | Description |
SSL_ERROR_NONE | No error occurred with the I/O call. |
SSL_ERROR_ZERO_RETURN | The operation failed due to the SSL session being closed. The underlying connection medium may still be open. |
SSL_ERROR_WANT_READ | The operation couldn't be completed. The underlying medium could not fulfill the read requested. This error code means the call should be retried. |
SSL_ERROR_WANT_WRITE | The operation couldn't be completed. The underlying medium could not fulfill the write requested. This error code means the call should be retried. |
5.2.2.3 Non-blocking I/O
5.2.3 SSL Renegotiations
SSL重新协商本质上是一个连接期间的SSL握手。