33#include <Security/Security.h>
35#ifdef SONAME_LIBGNUTLS
36#include <gnutls/pkcs12.h>
40#define WIN32_NO_STATUS
50#ifdef SONAME_LIBGNUTLS
55int gnutls_pkcs12_simple_parse(gnutls_pkcs12_t p12,
const char *
password,
56 gnutls_x509_privkey_t *
key, gnutls_x509_crt_t **
chain,
unsigned int *chain_len,
57 gnutls_x509_crt_t **extra_certs,
unsigned int *extra_certs_len,
58 gnutls_x509_crl_t *
crl,
unsigned int flags);
60int gnutls_x509_privkey_get_pk_algorithm2(gnutls_x509_privkey_t,
unsigned int*);
62static void *libgnutls_handle;
63#define MAKE_FUNCPTR(f) static typeof(f) * p##f
78static void gnutls_log(
int level,
const char *
msg )
88 if ((env_str =
getenv(
"GNUTLS_SYSTEM_PRIORITY_FILE")))
94 WARN(
"Setting GNUTLS_SYSTEM_PRIORITY_FILE to \"/dev/null\".\n");
95 setenv(
"GNUTLS_SYSTEM_PRIORITY_FILE",
"/dev/null", 0);
98 if (!(libgnutls_handle = dlopen( SONAME_LIBGNUTLS,
RTLD_NOW )))
100 ERR_(winediag)(
"failed to load libgnutls, no support for pfx import/export\n" );
104#define LOAD_FUNCPTR(f) \
105 if (!(p##f = dlsym( libgnutls_handle, #f ))) \
107 ERR( "failed to load %s\n", #f ); \
125 if ((
ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS)
127 pgnutls_perror(
ret );
133 char *
env =
getenv(
"GNUTLS_DEBUG_LEVEL");
135 pgnutls_global_set_log_level(
level);
136 pgnutls_global_set_log_function( gnutls_log );
142 dlclose( libgnutls_handle );
143 libgnutls_handle =
NULL;
149 pgnutls_global_deinit();
150 dlclose( libgnutls_handle );
151 libgnutls_handle =
NULL;
154#define RSA_MAGIC_KEY ('R' | ('S' << 8) | ('A' << 16) | ('2' << 24))
155#define RSA_PUBEXP 65537
157struct cert_store_data
160 gnutls_x509_privkey_t
key;
161 gnutls_x509_crt_t *
chain;
162 unsigned int key_bitlen;
163 unsigned int chain_len;
174 struct cert_store_data *
data = get_store_data(
params->data );
176 unsigned int bitlen =
data->key_bitlen;
177 gnutls_datum_t
m,
e,
d,
p,
q,
u, e1, e2;
183 size =
sizeof(*hdr) +
sizeof(*rsakey) + (bitlen * 9 / 16);
190 if ((
ret = pgnutls_x509_privkey_export_rsa_raw2(
data->key, &
m, &
e, &
d, &
p, &
q, &
u, &e1, &e2 )) < 0)
192 pgnutls_perror(
ret );
203 rsakey->
magic = RSA_MAGIC_KEY;
205 rsakey->
pubexp = RSA_PUBEXP;
208 if (
m.size == bitlen / 8 + 1 && !
m.data[0])
src =
m.data + 1;
209 else if (
m.size != bitlen / 8)
goto done;
211 for (
i = bitlen / 8 - 1;
i >= 0;
i--) *
dst++ =
src[
i];
213 if (
p.size == bitlen / 16 + 1 && !
p.data[0])
src =
p.data + 1;
214 else if (
p.size != bitlen / 16)
goto done;
216 for (
i = bitlen / 16 - 1;
i >= 0;
i--) *
dst++ =
src[
i];
218 if (
q.size == bitlen / 16 + 1 && !
q.data[0])
src =
q.data + 1;
219 else if (
q.size != bitlen / 16)
goto done;
221 for (
i = bitlen / 16 - 1;
i >= 0;
i--) *
dst++ =
src[
i];
223 if (e1.size == bitlen / 16 + 1 && !e1.data[0])
src = e1.data + 1;
224 else if (e1.size != bitlen / 16)
goto done;
226 for (
i = bitlen / 16 - 1;
i >= 0;
i--) *
dst++ =
src[
i];
228 if (e2.size == bitlen / 16 + 1 && !e2.data[0])
src = e2.data + 1;
229 else if (e2.size != bitlen / 16)
goto done;
231 for (
i = bitlen / 16 - 1;
i >= 0;
i--) *
dst++ =
src[
i];
233 if (
u.size == bitlen / 16 + 1 && !
u.data[0])
src =
u.data + 1;
234 else if (
u.size != bitlen / 16)
goto done;
236 for (
i = bitlen / 16 - 1;
i >= 0;
i--) *
dst++ =
src[
i];
238 if (
d.size == bitlen / 8 + 1 && !
d.data[0])
src =
d.data + 1;
239 else if (
d.size != bitlen / 8)
goto done;
241 for (
i = bitlen / 8 - 1;
i >= 0;
i--) *
dst++ =
src[
i];
255static char *password_to_ascii(
const WCHAR *
str )
263 if (*
str > 0x7f)
WARN(
"password contains non-ascii characters\n" );
274 gnutls_datum_t pfx_data;
275 gnutls_x509_privkey_t
key;
276 gnutls_x509_crt_t *
chain;
277 unsigned int chain_len;
281 struct cert_store_data *store_data;
286 if ((
ret = pgnutls_pkcs12_init( &p12 )) < 0)
goto error;
288 pfx_data.data =
params->pfx->pbData;
289 pfx_data.size =
params->pfx->cbData;
290 if ((
ret = pgnutls_pkcs12_import( p12, &pfx_data, GNUTLS_X509_FMT_DER, 0 )) < 0)
goto error;
295 if ((
ret = pgnutls_x509_privkey_get_pk_algorithm2(
key, &bitlen )) < 0)
300 if (
ret != GNUTLS_PK_RSA)
302 FIXME(
"key algorithm %u not supported\n",
ret );
303 pgnutls_pkcs12_deinit( p12 );
307 store_data =
malloc(
sizeof(*store_data) );
308 store_data->p12 = p12;
309 store_data->key =
key;
310 store_data->chain =
chain;
311 store_data->key_bitlen = bitlen;
312 store_data->chain_len = chain_len;
317 pgnutls_perror(
ret );
318 pgnutls_pkcs12_deinit( p12 );
326 struct cert_store_data *
data = get_store_data(
params->data );
332 if ((
ret = pgnutls_x509_crt_export(
data->chain[
params->index], GNUTLS_X509_FMT_DER,
NULL, &
size )) != GNUTLS_E_SHORT_MEMORY_BUFFER)
340 if ((
ret = pgnutls_x509_crt_export(
data->chain[
params->index], GNUTLS_X509_FMT_DER,
params->buf, &
size )) < 0)
349 struct cert_store_data *
data = get_store_data(
params->data );
353 pgnutls_pkcs12_deinit(
data->p12 );
417#define BASE64_DECODE_PADDING 0x100
418#define BASE64_DECODE_WHITESPACE 0x200
419#define BASE64_DECODE_INVALID 0x300
425 if (
c >=
'A' &&
c <=
'Z')
427 else if (
c >=
'a' &&
c <=
'z')
429 else if (
c >=
'0' &&
c <=
'9')
437 else if (
c ==
' ' ||
c ==
'\t' ||
c ==
'\r' ||
c ==
'\n')
464 if ((
valid & 3) == 0)
break;
472 if ((
valid & 3) != 0 && hasPadding)
return FALSE;
514 static const char header[] =
"-----BEGIN CERTIFICATE-----";
515 static const char trailer[] =
"-----END CERTIFICATE-----";
519 TRACE(
"begin new certificate\n");
525 TRACE(
"end of certificate, adding cert\n");
532 TRACE(
"Read %d certs\n", num_certs);
540 if (check_size > *buf_size)
545 *buf_size = check_size;
606 WARN(
"%s is a directory and directories are disallowed\n",
610 ERR(
"%s: invalid file type\n",
path);
617 "/etc/ssl/certs/ca-certificates.crt",
619 "/etc/pki/tls/certs/ca-bundle.crt",
620 "/usr/share/ca-certificates/ca-bundle.crt",
621 "/usr/local/share/certs/",
622 "/etc/sfw/openssl/certs",
623 "/etc/security/cacerts",
631 const SecTrustSettingsDomain domains[] = {
632 kSecTrustSettingsDomainSystem,
633 kSecTrustSettingsDomainAdmin,
634 kSecTrustSettingsDomainUser
642 status = SecTrustSettingsCopyCertificates(domains[
domain], &certs);
645 for (
i = 0;
i < CFArrayGetCount(certs);
i++)
647 SecCertificateRef
cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs,
i);
649 if ((
status = SecItemExport(
cert, kSecFormatX509Cert, 0,
NULL, &certData)) == noErr)
652 if (
data)
memcpy(
data, CFDataGetBytePtr(certData), CFDataGetLength(certData) );
656 WARN(
"could not export certificate %u to X509 format: 0x%08x\n",
i, (
unsigned int)
status);
719 }
const *params32 =
args;
721 const CRYPT_DATA_BLOB32 *pfx32 =
ULongToPtr( params32->pfx );
740 }
const *params32 =
args;
760 }
const *params32 =
args;
780 }
const *params32 =
args;
792const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
796 wow64_open_cert_store,
797 wow64_import_store_key,
798 wow64_import_store_cert,
800 wow64_enum_root_certs,
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
void pwd(int argc, const char *argv[])
static void list_remove(struct list_entry *entry)
static int list_empty(struct list_entry *head)
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
static LPCWSTR LPCWSTR LPCWSTR env
#define WINE_DECLARE_DEBUG_CHANNEL(x)
static void process_detach(void)
char *CDECL getenv(const char *name)
int CDECL fclose(FILE *file)
char *CDECL fgets(char *s, int size, FILE *file)
_ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl static FILE * fdopen(int fd, const char *mode)
_ACRTIMP int __cdecl atoi(const char *)
_ACRTIMP size_t __cdecl strlen(const char *)
_ACRTIMP int __cdecl strcmp(const char *, const char *)
_ACRTIMP int __cdecl strncmp(const char *, const char *, size_t)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLdouble GLdouble GLdouble GLdouble q
GLenum const GLfloat * params
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLuint GLsizei bufsize
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
#define memcpy(s1, s2, n)
#define STATUS_DLL_NOT_FOUND
#define STATUS_NO_MORE_ENTRIES
#define STATUS_DLL_INIT_FAILED
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
#define offsetof(TYPE, MEMBER)
int __cdecl closedir(DIR *)
DIR *__cdecl opendir(const char *)
struct dirent *__cdecl readdir(DIR *)
#define STATUS_BUFFER_TOO_SMALL
#define STATUS_INVALID_PARAMETER
static void import_certs_from_file(int fd)
static NTSTATUS import_store_key(void *args)
static const char *const CRYPT_knownLocations[]
const unixlib_entry_t __wine_unix_call_funcs[]
static BOOL base64_to_cert(const char *str)
static BYTE * add_cert(SIZE_T size)
#define BASE64_DECODE_PADDING
static NTSTATUS close_cert_store(void *args)
static void import_certs_from_dir(LPCSTR path)
static NTSTATUS enum_root_certs(void *args)
static void add_line_to_buffer(struct DynamicBuffer *buffer, LPCSTR line)
static NTSTATUS import_store_cert(void *args)
#define BASE64_DECODE_WHITESPACE
static void import_certs_from_path(LPCSTR path, BOOL allow_dir)
static NTSTATUS process_attach(void *args)
#define BASE64_DECODE_INVALID
static void reset_buffer(struct DynamicBuffer *buffer)
static struct list root_cert_list
static int decodeBase64Byte(char c)
static void load_root_certs(void)
static BOOL check_buffer_resize(char **ptr_buf, size_t *buf_size, size_t check_size)
static NTSTATUS open_cert_store(void *args)
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
static unsigned int block