1
/********************************************************************
3
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. *
4
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2013 *
9
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
11
********************************************************************/
13
/*This should really be part of OpenSSL, but there's been a patch [1] sitting
14
in their bugtracker for over two years that implements this, without any
15
action, so I'm giving up and re-implementing it locally.
17
[1] <http://rt.openssl.org/Ticket/Display.html?id=2158>*/
20
#if defined(OP_ENABLE_HTTP)&&defined(_WIN32)
21
/*You must include windows.h before wincrypt.h and x509.h.*/
22
# define WIN32_LEAN_AND_MEAN
23
# define WIN32_EXTRA_LEAN
25
/*You must include wincrypt.h before x509.h, too, or X509_NAME doesn't get
27
# include <wincrypt.h>
28
# include <openssl/ssl.h>
29
# include <openssl/err.h>
30
# include <openssl/x509.h>
32
static int op_capi_new(X509_LOOKUP *_lu){
34
h_store=CertOpenStore(CERT_STORE_PROV_SYSTEM_A,0,0,
35
CERT_STORE_OPEN_EXISTING_FLAG|CERT_STORE_READONLY_FLAG|
36
CERT_SYSTEM_STORE_CURRENT_USER|CERT_STORE_SHARE_CONTEXT_FLAG,"ROOT");
38
_lu->method_data=(char *)h_store;
44
static void op_capi_free(X509_LOOKUP *_lu){
46
h_store=(HCERTSTORE)_lu->method_data;
47
# if defined(OP_ENABLE_ASSERTIONS)
48
OP_ALWAYS_TRUE(CertCloseStore(h_store,CERT_CLOSE_STORE_CHECK_FLAG));
50
CertCloseStore(h_store,0);
54
static int op_capi_retrieve_by_subject(X509_LOOKUP *_lu,int _type,
55
X509_NAME *_name,X509_OBJECT *_ret){
57
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
58
obj=X509_OBJECT_retrieve_by_subject(_lu->store_ctx->objs,_type,_name);
59
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
62
memcpy(&_ret->data,&obj->data,sizeof(_ret->data));
68
static int op_capi_get_by_subject(X509_LOOKUP *_lu,int _type,X509_NAME *_name,
71
if(_name==NULL)return 0;
72
if(_name->bytes==NULL||_name->bytes->length<=0||_name->modified){
73
if(i2d_X509_NAME(_name,NULL)<0)return 0;
74
OP_ASSERT(_name->bytes->length>0);
76
h_store=(HCERTSTORE)_lu->method_data;
79
CERT_NAME_BLOB find_para;
83
/*Although X509_NAME contains a canon_enc field, that "canonical" [1]
84
encoding was just made up by OpenSSL.
85
It doesn't correspond to any actual standard, and since it drops the
86
initial sequence header, won't be recognized by the Crypto API.
87
The assumption here is that CertFindCertificateInStore() will allow any
88
appropriate variations in the encoding when it does its comparison.
89
This is, however, emphatically not true under Wine, which just compares
90
the encodings with memcmp().
91
Most of the time things work anyway, though, and there isn't really
92
anything we can do to make the situation better.
94
[1] A "canonical form" is defined as the one where, if you locked 10
95
mathematicians in a room and asked them to come up with a
96
representation for something, it's the answer that 9 of them would
98
I don't think OpenSSL's encoding qualifies.*/
99
find_para.cbData=_name->bytes->length;
100
find_para.pbData=(unsigned char *)_name->bytes->data;
101
cert=CertFindCertificateInStore(h_store,X509_ASN_ENCODING,0,
102
CERT_FIND_SUBJECT_NAME,&find_para,NULL);
103
if(cert==NULL)return 0;
104
x=d2i_X509(NULL,(const unsigned char **)&cert->pbCertEncoded,
105
cert->cbCertEncoded);
106
CertFreeCertificateContext(cert);
108
ret=X509_STORE_add_cert(_lu->store_ctx,x);
110
if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
114
CERT_CONTEXT find_para;
118
ret=op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
120
memset(&cert_info,0,sizeof(cert_info));
121
cert_info.Issuer.cbData=_name->bytes->length;
122
cert_info.Issuer.pbData=(unsigned char *)_name->bytes->data;
123
memset(&find_para,0,sizeof(find_para));
124
find_para.pCertInfo=&cert_info;
125
crl=CertFindCRLInStore(h_store,0,0,CRL_FIND_ISSUED_BY,&find_para,NULL);
126
if(crl==NULL)return 0;
127
x=d2i_X509_CRL(NULL,(const unsigned char **)&crl->pbCrlEncoded,
129
CertFreeCRLContext(crl);
131
ret=X509_STORE_add_crl(_lu->store_ctx,x);
133
if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
139
/*This is not const because OpenSSL doesn't allow it, even though it won't
141
static X509_LOOKUP_METHOD X509_LOOKUP_CAPI={
142
"Load Crypto API store into cache",
148
op_capi_get_by_subject,
154
int SSL_CTX_set_default_verify_paths_win32(SSL_CTX *_ssl_ctx){
157
/*We intentionally do not add the normal default paths, as they are usually
158
wrong, and are just asking to be used as an exploit vector.*/
159
store=SSL_CTX_get_cert_store(_ssl_ctx);
160
OP_ASSERT(store!=NULL);
161
lu=X509_STORE_add_lookup(store,&X509_LOOKUP_CAPI);
162
if(lu==NULL)return 0;