Ulr*_*use 5 ssl proxy openssl visual-studio-2010 visual-studio
我创建了一个 DSAPI 过滤器来使用客户端证书对用户进行身份验证。用户通过代理连接,代理将用户的证书添加到请求标头中。
#define HDR_SSL_CLIENT_CERT "SSL_CLIENT_CERT"
Run Code Online (Sandbox Code Playgroud)
我使用 Apache 作为 HTTPS 代理;客户使用 NGINX。我已经发现 NGINX 添加了 TABS 而不是空格,并且我还确保证书数据在由我的代码解析之前具有正确的格式
#define BUFFER_SIZE 4096
char certData[BUFFER_SIZE+1] = {0,};
Run Code Online (Sandbox Code Playgroud)
certData 包含证书的 Base64 表示形式( TABS 和 SPACES 被替换为 \n)
-----BEGIN CERTIFICATE-----
MIIDOTCCAiGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJERTEO
MAwGA1UECgwFRE9TWVMxETAPBgNVBAsMCFRSQVZFTEVSMRQwEgYDVQQDDAtUUkFW
RUxFUiBDQTAeFw0xNjA0MTgxMzA2MjdaFw0yNjA0MTgxMzA2MjdaMBUxEzARBgNV
BAMMCkdlb3JnIER1bWEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCG
ctEsl++/4LgK8RJId2NUPJgjFKDl76jp38GNMtcCqt+ADUPvR+suoy/zeuRXs7hw
25YAx49U/FYFlu3Xlmb57ACyPtbhLPpV2Y8fJ0EXD2pY1G3oEWlKWWk6ErT2vg7V
ppOajckkx3EmkVrALhQgdOqQDHJ6Y2xQSgpKWGORmoEtYQepJ/LGWBfE4muZjUJk
euUf0fmHFehMw8X0ErPDFxDuAH+d7kjjUl+EqSQCqLqqrg50GMrM0vKIqyqqbUQF
wLQYyFllYkj0h1VQ+KhyxwVkq2snR+Z2EJe1A7xsUwY5D/9dVK5ih6xeIrpgvgCd
6Amx2KF9lh8yEZi1NMPPAgMBAAGjYzBhMB8GA1UdEQQYMBaBFEdlb3JnRHVtYUBz
dGFkdGRvLmRlMB0GA1UdDgQWBBRIX2fz2ahSFgOCf03W4pn9t/BomjAfBgNVHSME
GDAWgBR7RJ1HsYOVlc4TOAzeqIqETopeCTANBgkqhkiG9w0BAQsFAAOCAQEALWre
gJYsSD6i3e4MhJOhR0FFincqdnVEeEoVMr4GDSZRMUPSTjNMTdGLLMFHpU9p/cGZ
4b30k7dQWhIao7aLIgDOXaATr14fLXrZqRM/MXusd27nFKQRZf1ktrxr0vIZqnw4
SuniS3NP7SuVEbUeTWU8nVub17aUWX8T4C8yAHKmancSSgMXwFhXTNq0aIvwRzIv
TzyK0SDXSc68kQkf3evTRvKfvlmQGWXL6BukTGJS1870x3IrDK19Phi5PUYXQtZV
uwaRg1fRUyPno0GCIZiMxCY4rWy+AaM3CO7Ua5+KEiAdWKrBP6Jd24hZuH8ZhuZ/
9u5SSvUA1bGAT02eqQ==
-----END CERTIFICATE-----
Run Code Online (Sandbox Code Playgroud)
然后,我使用以下代码从 certData 获取 X509:
BIO * bio = BIO_new(BIO_s_mem());
X509 * clientCert = X509_new();
bio = BIO_new_mem_buf(certData, -1);
PEM_read_bio_X509(bio, &clientCert, 0, NULL);
if (clientCert == NULL) {
debugOut("PEM_read_bio_X509 failed...\n");
if(bio) {
BIO_free(bio);
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
在 Apache 中使用 DSAPI 时,我们没有发现任何问题;NGINX 也可以工作。但有时 PEM_read_bio_X509 会失败并且不会创建 clientCert。
我的代码有什么明显的错误吗?
PEM_read_bio_X509 和 NGINX 是否存在已知问题?
我现在使用的是 openSSL 1.0.1p。
更新:这是替换 TABS 和 SPACES 的代码
char szHeaderAuthToken[MAX_BUF_LEN+1] = {0,};
Run Code Online (Sandbox Code Playgroud)
包含代理提交的数据
size_t last = certLen - lastblank;
while (szHeaderClientCert[j] != '\0') {
c = szHeaderClientCert[j];
// skip first and last 'space' char
if (j == 10 || j == last) {
c = ' ';
} else {
if (isspace(c) || ('\t' == c) ) c = '\n';
}
certData[j] = c;
if (DEBUGOUT) {
putchar (c);
ofs << c;
}
j++;
}
certData[j+1] = '\0';
Run Code Online (Sandbox Code Playgroud)
UPDATE2:好的和坏的 certData
20160512_145926 GOOD
-----BEGIN CERTIFICATE-----
MIIDOTCCAiGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJERTEO
MAwGA1UECgwFRE9TWVMxETAPBgNVBAsMCFRSQVZFTEVSMRQwEgYDVQQDDAtUUkFW
RUxFUiBDQTAeFw0xNjA0MTgxMzA2MjdaFw0yNjA0MTgxMzA2MjdaMBUxEzARBgNV
BAMMCkdlb3JnIER1bWEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCG
ctEsl++/4LgK8RJId2NUPJgjFKDl76jp38GNMtcCqt+ADUPvR+suoy/zeuRXs7hw
25YAx49U/FYFlu3Xlmb57ACyPtbhLPpV2Y8fJ0EXD2pY1G3oEWlKWWk6ErT2vg7V
ppOajckkx3EmkVrALhQgdOqQDHJ6Y2xQSgpKWGORmoEtYQepJ/LGWBfE4muZjUJk
euUf0fmHFehMw8X0ErPDFxDuAH+d7kjjUl+EqSQCqLqqrg50GMrM0vKIqyqqbUQF
wLQYyFllYkj0h1VQ+KhyxwVkq2snR+Z2EJe1A7xsUwY5D/9dVK5ih6xeIrpgvgCd
6Amx2KF9lh8yEZi1NMPPAgMBAAGjYzBhMB8GA1UdEQQYMBaBFEdlb3JnRHVtYUBz
dGFkdGRvLmRlMB0GA1UdDgQWBBRIX2fz2ahSFgOCf03W4pn9t/BomjAfBgNVHSME
GDAWgBR7RJ1HsYOVlc4TOAzeqIqETopeCTANBgkqhkiG9w0BAQsFAAOCAQEALWre
gJYsSD6i3e4MhJOhR0FFincqdnVEeEoVMr4GDSZRMUPSTjNMTdGLLMFHpU9p/cGZ
4b30k7dQWhIao7aLIgDOXaATr14fLXrZqRM/MXusd27nFKQRZf1ktrxr0vIZqnw4
SuniS3NP7SuVEbUeTWU8nVub17aUWX8T4C8yAHKmancSSgMXwFhXTNq0aIvwRzIv
TzyK0SDXSc68kQkf3evTRvKfvlmQGWXL6BukTGJS1870x3IrDK19Phi5PUYXQtZV
uwaRg1fRUyPno0GCIZiMxCY4rWy+AaM3CO7Ua5+KEiAdWKrBP6Jd24hZuH8ZhuZ/
9u5SSvUA1bGAT02eqQ==
-----END CERTIFICATE-----
20160512_150227 FAIL
-----BEGIN CERTIFICATE-----
MIIDOTCCAiGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJERTEO
MAwGA1UECgwFRE9TWVMxETAPBgNVBAsMCFRSQVZFTEVSMRQwEgYDVQQDDAtUUkFW
RUxFUiBDQTAeFw0xNjA0MTgxMzA2MjdaFw0yNjA0MTgxMzA2MjdaMBUxEzARBgNV
BAMMCkdlb3JnIER1bWEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCG
ctEsl++/4LgK8RJId2NUPJgjFKDl76jp38GNMtcCqt+ADUPvR+suoy/zeuRXs7hw
25YAx49U/FYFlu3Xlmb57ACyPtbhLPpV2Y8fJ0EXD2pY1G3oEWlKWWk6ErT2vg7V
ppOajckkx3EmkVrALhQgdOqQDHJ6Y2xQSgpKWGORmoEtYQepJ/LGWBfE4muZjUJk
euUf0fmHFehMw8X0ErPDFxDuAH+d7kjjUl+EqSQCqLqqrg50GMrM0vKIqyqqbUQF
wLQYyFllYkj0h1VQ+KhyxwVkq2snR+Z2EJe1A7xsUwY5D/9dVK5ih6xeIrpgvgCd
6Amx2KF9lh8yEZi1NMPPAgMBAAGjYzBhMB8GA1UdEQQYMBaBFEdlb3JnRHVtYUBz
dGFkdGRvLmRlMB0GA1UdDgQWBBRIX2fz2ahSFgOCf03W4pn9t/BomjAfBgNVHSME
GDAWgBR7RJ1HsYOVlc4TOAzeqIqETopeCTANBgkqhkiG9w0BAQsFAAOCAQEALWre
gJYsSD6i3e4MhJOhR0FFincqdnVEeEoVMr4GDSZRMUPSTjNMTdGLLMFHpU9p/cGZ
4b30k7dQWhIao7aLIgDOXaATr14fLXrZqRM/MXusd27nFKQRZf1ktrxr0vIZqnw4
SuniS3NP7SuVEbUeTWU8nVub17aUWX8T4C8yAHKmancSSgMXwFhXTNq0aIvwRzIv
TzyK0SDXSc68kQkf3evTRvKfvlmQGWXL6BukTGJS1870x3IrDK19Phi5PUYXQtZV
uwaRg1fRUyPno0GCIZiMxCY4rWy+AaM3CO7Ua5+KEiAdWKrBP6Jd24hZuH8ZhuZ/
9u5SSvUA1bGAT02eqQ==
-----END CERTIFICATE-----
20160512_150227 PEM_read_bio_X509 failed...
Run Code Online (Sandbox Code Playgroud)
您可以在运行替换空格的函数后显示 PEM 文本吗?
这很可疑:
if (j == 10 || j == last) {
c = ' ';
Run Code Online (Sandbox Code Playgroud)
因为你实际上并没有检查该位置是否有空格。您可能会覆盖非 SPACE 的内容。
这很可疑:
if (isspace(c) || ('\t' == c) ) c = '\n';
Run Code Online (Sandbox Code Playgroud)
因为例如,如果换行符之前恰好有一个空格,这很容易导致连续两个换行符。
行尾的空格后跟单个换行符是可以的,但是 PEM 数据中间的一行中的两个换行符不起作用,并且会导致:
unable to load certificate
27748:error:0906B06B:PEM routines:PEM_get_EVP_CIPHER_INFO:not proc type:pem_lib.c:446:
Run Code Online (Sandbox Code Playgroud)
例如。一个简单的:
$ echo "...your bad cert output from above..." | openssl x509 -noout -text
Run Code Online (Sandbox Code Playgroud)
在这里工作得很好。
编辑:我见过 NGINX 在 PEM 的每一行前面放了空格——我不记得细节了。但我会在 NGINX 中使用 HTTP_SSL_CLIENT_RAW_CERT。
编辑2:通过HTTP_SSL_CLIENT_RAW_CERT,我的意思是,使用来自nginx的$ssl_client_raw_cert而不是$ssl_client_cert。使用 $ssl_client_cert 时,您必须从每行 PEM 数据的开头删除制表符。
归档时间: |
|
查看次数: |
3414 次 |
最近记录: |