~ubuntu-branches/ubuntu/trusty/opusfile/trusty

« back to all changes in this revision

Viewing changes to src/wincerts.c

  • Committer: Package Import Robot
  • Author(s): Ron Lee
  • Date: 2013-05-13 21:43:40 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20130513214340-9p3jj0irk8afk7kd
Tags: 0.2+20130513-1
* Snapshot release for unstable.
* Fixes the pkg-config file to avoid overlinking.  Closes: #707969
* Split the URL handling into a separate library, so that linking with
  openssl is only an issue for people who do need that functionality.
  The main opusfile library can now be linked with anything again.
  Closes:  #708008

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/********************************************************************
 
2
 *                                                                  *
 
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.       *
 
7
 *                                                                  *
 
8
 * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2013                *
 
9
 * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
 
10
 *                                                                  *
 
11
 ********************************************************************/
 
12
 
 
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.
 
16
 
 
17
  [1] <http://rt.openssl.org/Ticket/Display.html?id=2158>*/
 
18
 
 
19
#include "internal.h"
 
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
 
24
# include <windows.h>
 
25
/*You must include wincrypt.h before x509.h, too, or X509_NAME doesn't get
 
26
   defined properly.*/
 
27
# include <wincrypt.h>
 
28
# include <openssl/ssl.h>
 
29
# include <openssl/err.h>
 
30
# include <openssl/x509.h>
 
31
 
 
32
static int op_capi_new(X509_LOOKUP *_lu){
 
33
  HCERTSTORE h_store;
 
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");
 
37
  if(h_store!=NULL){
 
38
    _lu->method_data=(char *)h_store;
 
39
    return 1;
 
40
  }
 
41
  return 0;
 
42
}
 
43
 
 
44
static void op_capi_free(X509_LOOKUP *_lu){
 
45
  HCERTSTORE h_store;
 
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));
 
49
# else
 
50
  CertCloseStore(h_store,0);
 
51
# endif
 
52
}
 
53
 
 
54
static int op_capi_retrieve_by_subject(X509_LOOKUP *_lu,int _type,
 
55
 X509_NAME *_name,X509_OBJECT *_ret){
 
56
  X509_OBJECT *obj;
 
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);
 
60
  if(obj!=NULL){
 
61
    _ret->type=obj->type;
 
62
    memcpy(&_ret->data,&obj->data,sizeof(_ret->data));
 
63
    return 1;
 
64
  }
 
65
  return 0;
 
66
}
 
67
 
 
68
static int op_capi_get_by_subject(X509_LOOKUP *_lu,int _type,X509_NAME *_name,
 
69
 X509_OBJECT *_ret){
 
70
  HCERTSTORE h_store;
 
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);
 
75
  }
 
76
  h_store=(HCERTSTORE)_lu->method_data;
 
77
  switch(_type){
 
78
    case X509_LU_X509:{
 
79
      CERT_NAME_BLOB  find_para;
 
80
      PCCERT_CONTEXT  cert;
 
81
      X509           *x;
 
82
      int             ret;
 
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.
 
93
 
 
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
 
97
         give you back.
 
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);
 
107
      if(x==NULL)return 0;
 
108
      ret=X509_STORE_add_cert(_lu->store_ctx,x);
 
109
      X509_free(x);
 
110
      if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
 
111
    }break;
 
112
    case X509_LU_CRL:{
 
113
      CERT_INFO      cert_info;
 
114
      CERT_CONTEXT   find_para;
 
115
      PCCRL_CONTEXT  crl;
 
116
      X509_CRL      *x;
 
117
      int            ret;
 
118
      ret=op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
 
119
      if(ret>0)return 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,
 
128
       crl->cbCrlEncoded);
 
129
      CertFreeCRLContext(crl);
 
130
      if(x==NULL)return 0;
 
131
      ret=X509_STORE_add_crl(_lu->store_ctx,x);
 
132
      X509_CRL_free(x);
 
133
      if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
 
134
    }break;
 
135
  }
 
136
  return 0;
 
137
}
 
138
 
 
139
/*This is not const because OpenSSL doesn't allow it, even though it won't
 
140
   write to it.*/
 
141
static X509_LOOKUP_METHOD X509_LOOKUP_CAPI={
 
142
  "Load Crypto API store into cache",
 
143
  op_capi_new,
 
144
  op_capi_free,
 
145
  NULL,
 
146
  NULL,
 
147
  NULL,
 
148
  op_capi_get_by_subject,
 
149
  NULL,
 
150
  NULL,
 
151
  NULL
 
152
};
 
153
 
 
154
int SSL_CTX_set_default_verify_paths_win32(SSL_CTX *_ssl_ctx){
 
155
  X509_STORE  *store;
 
156
  X509_LOOKUP *lu;
 
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;
 
163
  ERR_clear_error();
 
164
  return 1;
 
165
}
 
166
 
 
167
#endif