win32-certstore 0.1.0 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +228 -225
- data/lib/win32/certstore.rb +1 -1
- data/lib/win32/certstore/mixin/assertions.rb +90 -90
- data/lib/win32/certstore/mixin/crypto.rb +203 -203
- data/lib/win32/certstore/mixin/helper.rb +50 -50
- data/lib/win32/certstore/mixin/shell_out.rb +105 -104
- data/lib/win32/certstore/mixin/string.rb +71 -71
- data/lib/win32/certstore/mixin/unicode.rb +50 -50
- data/lib/win32/certstore/store_base.rb +215 -214
- data/lib/win32/certstore/version.rb +6 -6
- metadata +3 -3
data/lib/win32/certstore.rb
CHANGED
@@ -1,90 +1,90 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Piyush Awasthi (<piyush.awasthi@msystechnologies.com>)
|
3
|
-
# Copyright:: Copyright (c) 2017 Chef Software, Inc.
|
4
|
-
# License:: Apache License, Version 2.0
|
5
|
-
#
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
-
# you may not use this file except in compliance with the License.
|
8
|
-
# You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
# See the License for the specific language governing permissions and
|
16
|
-
# limitations under the License.
|
17
|
-
require "openssl"
|
18
|
-
|
19
|
-
module Win32
|
20
|
-
class Certstore
|
21
|
-
module Mixin
|
22
|
-
module Assertions
|
23
|
-
# Validate certificate store name
|
24
|
-
def validate_store(store_name)
|
25
|
-
unless valid_store_name.include?(store_name
|
26
|
-
raise ArgumentError, "Invalid Certificate Store."
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# Validate certificate type
|
31
|
-
def validate_certificate(cert_file_path)
|
32
|
-
unless !cert_file_path.nil? && File.extname(cert_file_path) =~ /.cer|.crt|.pfx|.der/
|
33
|
-
raise ArgumentError, "Invalid Certificate format."
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# Validate certificate Object
|
38
|
-
def validate_certificate_obj(cert_obj)
|
39
|
-
unless cert_obj.class == OpenSSL::X509::Certificate
|
40
|
-
raise ArgumentError, "Invalid Certificate object."
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# Validate thumbprint
|
45
|
-
def validate_thumbprint(cert_thumbprint)
|
46
|
-
if cert_thumbprint.nil? || cert_thumbprint.strip.empty?
|
47
|
-
raise ArgumentError, "Invalid certificate thumbprint."
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# Validate certificate name not nil/empty
|
52
|
-
def validate!(token)
|
53
|
-
raise ArgumentError, "Invalid search token" if !token || token.strip.empty?
|
54
|
-
end
|
55
|
-
|
56
|
-
# Common System call errors
|
57
|
-
def lookup_error(failed_operation = nil)
|
58
|
-
error_no = FFI::LastError.error
|
59
|
-
case error_no
|
60
|
-
when 1223
|
61
|
-
raise SystemCallError.new("The operation was canceled by the user", error_no)
|
62
|
-
when -2146885628
|
63
|
-
raise SystemCallError.new("Cannot find object or property", error_no)
|
64
|
-
when -2146885629
|
65
|
-
raise SystemCallError.new("An error occurred while reading or writing to a file.", error_no)
|
66
|
-
when -2146881269
|
67
|
-
raise SystemCallError.new("ASN1 bad tag value met. -- Is the certificate in DER format?", error_no)
|
68
|
-
when -2146881278
|
69
|
-
raise SystemCallError.new("ASN1 unexpected end of data.", error_no)
|
70
|
-
when -2147024891
|
71
|
-
raise SystemCallError.new("System.UnauthorizedAccessException, Access denied..", error_no)
|
72
|
-
else
|
73
|
-
raise SystemCallError.new("Unable to #{failed_operation} certificate.", error_no)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
# These Are Valid certificate store name
|
80
|
-
# CA -> Certification authority certificates.
|
81
|
-
# MY -> A certificate store that holds certificates with associated private keys.
|
82
|
-
# ROOT -> Root certificates.
|
83
|
-
# SPC -> Software Publisher Certificate.
|
84
|
-
def valid_store_name
|
85
|
-
%w{MY CA ROOT SPC}
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
1
|
+
#
|
2
|
+
# Author:: Piyush Awasthi (<piyush.awasthi@msystechnologies.com>)
|
3
|
+
# Copyright:: Copyright (c) 2017 Chef Software, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
require "openssl"
|
18
|
+
|
19
|
+
module Win32
|
20
|
+
class Certstore
|
21
|
+
module Mixin
|
22
|
+
module Assertions
|
23
|
+
# Validate certificate store name
|
24
|
+
def validate_store(store_name)
|
25
|
+
unless valid_store_name.include?(store_name.to_s.upcase)
|
26
|
+
raise ArgumentError, "Invalid Certificate Store."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Validate certificate type
|
31
|
+
def validate_certificate(cert_file_path)
|
32
|
+
unless !cert_file_path.nil? && File.extname(cert_file_path) =~ /.cer|.crt|.pfx|.der/
|
33
|
+
raise ArgumentError, "Invalid Certificate format."
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Validate certificate Object
|
38
|
+
def validate_certificate_obj(cert_obj)
|
39
|
+
unless cert_obj.class == OpenSSL::X509::Certificate
|
40
|
+
raise ArgumentError, "Invalid Certificate object."
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Validate thumbprint
|
45
|
+
def validate_thumbprint(cert_thumbprint)
|
46
|
+
if cert_thumbprint.nil? || cert_thumbprint.strip.empty?
|
47
|
+
raise ArgumentError, "Invalid certificate thumbprint."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Validate certificate name not nil/empty
|
52
|
+
def validate!(token)
|
53
|
+
raise ArgumentError, "Invalid search token" if !token || token.strip.empty?
|
54
|
+
end
|
55
|
+
|
56
|
+
# Common System call errors
|
57
|
+
def lookup_error(failed_operation = nil)
|
58
|
+
error_no = FFI::LastError.error
|
59
|
+
case error_no
|
60
|
+
when 1223
|
61
|
+
raise SystemCallError.new("The operation was canceled by the user", error_no)
|
62
|
+
when -2146885628
|
63
|
+
raise SystemCallError.new("Cannot find object or property", error_no)
|
64
|
+
when -2146885629
|
65
|
+
raise SystemCallError.new("An error occurred while reading or writing to a file.", error_no)
|
66
|
+
when -2146881269
|
67
|
+
raise SystemCallError.new("ASN1 bad tag value met. -- Is the certificate in DER format?", error_no)
|
68
|
+
when -2146881278
|
69
|
+
raise SystemCallError.new("ASN1 unexpected end of data.", error_no)
|
70
|
+
when -2147024891
|
71
|
+
raise SystemCallError.new("System.UnauthorizedAccessException, Access denied..", error_no)
|
72
|
+
else
|
73
|
+
raise SystemCallError.new("Unable to #{failed_operation} certificate.", error_no)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# These Are Valid certificate store name
|
80
|
+
# CA -> Certification authority certificates.
|
81
|
+
# MY -> A certificate store that holds certificates with associated private keys.
|
82
|
+
# ROOT -> Root certificates.
|
83
|
+
# SPC -> Software Publisher Certificate.
|
84
|
+
def valid_store_name
|
85
|
+
%w{MY CA ROOT AUTHROOT DISALLOWED SPC TRUST TRUSTEDPEOPLE TRUSTEDPUBLISHER CLIENTAUTHISSUER TRUSTEDDEVICES SMARTCARDROOT WEBHOSTING REMOTE\ DESKTOP}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -1,203 +1,203 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Nimisha Sharad (<nimisha.sharad@msystechnologies.com>)
|
3
|
-
# Copyright:: Copyright (c) 2017 Chef Software, Inc.
|
4
|
-
# License:: Apache License, Version 2.0
|
5
|
-
#
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
-
# you may not use this file except in compliance with the License.
|
8
|
-
# You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
# See the License for the specific language governing permissions and
|
16
|
-
# limitations under the License.
|
17
|
-
#
|
18
|
-
|
19
|
-
require "ffi"
|
20
|
-
|
21
|
-
module Win32
|
22
|
-
class Certstore
|
23
|
-
module Mixin
|
24
|
-
module Crypto
|
25
|
-
extend FFI::Library
|
26
|
-
|
27
|
-
ffi_lib "Crypt32"
|
28
|
-
ffi_convention :stdcall
|
29
|
-
|
30
|
-
# Attempts to use FFI's attach_function method to link a native Win32
|
31
|
-
# function into the calling module. If this fails a dummy method is
|
32
|
-
# defined which when called, raises a helpful exception to the end-user.
|
33
|
-
module FFI::Library
|
34
|
-
def safe_attach_function(win32_func, *args)
|
35
|
-
attach_function(win32_func.to_sym, *args)
|
36
|
-
rescue FFI::NotFoundError
|
37
|
-
define_method(win32_func.to_sym) do |*margs|
|
38
|
-
raise NotImplementedError, "This version of Windows does not implement the Win32 function [#{win32_func}]."
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
###############################################
|
44
|
-
# Win32 API Constants
|
45
|
-
###############################################
|
46
|
-
|
47
|
-
CERT_CLOSE_STORE_CHECK_FLAG = 0
|
48
|
-
CERT_CLOSE_STORE_FORCE_FLAG = 1
|
49
|
-
|
50
|
-
# cert encoding flags.
|
51
|
-
CRYPT_ASN_ENCODING = 0x00000001
|
52
|
-
CRYPT_NDR_ENCODING = 0x00000002
|
53
|
-
X509_ASN_ENCODING = 0x00000001
|
54
|
-
X509_NDR_ENCODING = 0x00000002
|
55
|
-
PKCS_7_ASN_ENCODING = 0x00010000
|
56
|
-
PKCS_7_NDR_ENCODING = 0x00020000
|
57
|
-
PKCS_7_OR_X509_ASN_ENCODING = (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
|
58
|
-
|
59
|
-
# Certificate Display Format
|
60
|
-
CERT_NAME_EMAIL_TYPE = 1
|
61
|
-
CERT_NAME_RDN_TYPE = 2
|
62
|
-
CERT_NAME_ATTR_TYPE = 3
|
63
|
-
CERT_NAME_SIMPLE_DISPLAY_TYPE = 4
|
64
|
-
CERT_NAME_FRIENDLY_DISPLAY_TYPE = 5
|
65
|
-
CERT_NAME_DNS_TYPE = 6
|
66
|
-
CERT_NAME_URL_TYPE = 7
|
67
|
-
CERT_NAME_UPN_TYPE = 8
|
68
|
-
|
69
|
-
# Retrieve Certificates flag
|
70
|
-
CERT_FIND_SUBJECT_STR = 0x00080007
|
71
|
-
CERT_FIND_ISSUER_STR = 0x00080004
|
72
|
-
|
73
|
-
# List Certificates Flag
|
74
|
-
CERT_NAME_ISSUER_FLAG = 0x1
|
75
|
-
CERT_NAME_DISABLE_IE4_UTF8_FLAG = 0x00010000
|
76
|
-
CERT_NAME_SEARCH_ALL_NAMES_FLAG = 0x2
|
77
|
-
CERT_NAME_STR_ENABLE_PUNYCODE_FLAG = 0x00200000
|
78
|
-
|
79
|
-
# Define ffi pointer
|
80
|
-
HCERTSTORE = FFI::TypeDefs[:pointer]
|
81
|
-
HCRYPTPROV_LEGACY = FFI::TypeDefs[:pointer]
|
82
|
-
PCCERT_CONTEXT = FFI::TypeDefs[:pointer]
|
83
|
-
BYTE = FFI::TypeDefs[:pointer]
|
84
|
-
DWORD = FFI::TypeDefs[:uint32]
|
85
|
-
BLOB = FFI::TypeDefs[:ulong]
|
86
|
-
LPSTR = FFI::TypeDefs[:pointer]
|
87
|
-
LPCTSTR = FFI::TypeDefs[:pointer]
|
88
|
-
BOOL = FFI::TypeDefs[:bool]
|
89
|
-
INT_PTR = FFI::TypeDefs[:int]
|
90
|
-
LONG = FFI::TypeDefs[:long]
|
91
|
-
LPVOID = FFI::TypeDefs[:pointer]
|
92
|
-
LPTSTR = FFI::TypeDefs[:pointer]
|
93
|
-
LMSTR = FFI::TypeDefs[:pointer]
|
94
|
-
PWSTR = FFI::TypeDefs[:pointer]
|
95
|
-
LPFILETIME = FFI::TypeDefs[:pointer]
|
96
|
-
PCERT_INFO = FFI::TypeDefs[:pointer]
|
97
|
-
PCTL_USAGE = FFI::TypeDefs[:pointer]
|
98
|
-
PCTL_VERIFY_USAGE_PARA = FFI::TypeDefs[:pointer]
|
99
|
-
PCTL_VERIFY_USAGE_STATUS = FFI::TypeDefs[:pointer]
|
100
|
-
|
101
|
-
class FILETIME < FFI::Struct
|
102
|
-
layout :dwLowDateTime, DWORD,
|
103
|
-
:dwHighDateTime, DWORD
|
104
|
-
end
|
105
|
-
|
106
|
-
class CRYPT_INTEGER_BLOB < FFI::Struct
|
107
|
-
layout :cbData, DWORD, # Count, in bytes, of data
|
108
|
-
:pbData, :pointer # Pointer to data buffer
|
109
|
-
end
|
110
|
-
|
111
|
-
class CRYPT_NAME_BLOB < FFI::Struct
|
112
|
-
layout :cbData, DWORD, # Count, in bytes, of data
|
113
|
-
:pbData, :pointer # Pointer to data buffer
|
114
|
-
def initialize(str = nil)
|
115
|
-
super(nil)
|
116
|
-
if str
|
117
|
-
self[:pbData] = FFI::MemoryPointer.new(2, 128)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
class CERT_EXTENSION < FFI::Struct
|
123
|
-
layout :pszObjId, LPTSTR,
|
124
|
-
:fCritical, BOOL,
|
125
|
-
:Value, CRYPT_INTEGER_BLOB
|
126
|
-
end
|
127
|
-
|
128
|
-
class CRYPT_BIT_BLOB < FFI::Struct
|
129
|
-
layout :cbData, DWORD,
|
130
|
-
:pbData, BYTE,
|
131
|
-
:cUnusedBits, DWORD
|
132
|
-
end
|
133
|
-
|
134
|
-
class CRYPT_ALGORITHM_IDENTIFIER < FFI::Struct
|
135
|
-
layout :pszObjId, LPSTR,
|
136
|
-
:Parameters, CRYPT_INTEGER_BLOB
|
137
|
-
end
|
138
|
-
|
139
|
-
class CERT_PUBLIC_KEY_INFO < FFI::Struct
|
140
|
-
layout :Algorithm, CRYPT_ALGORITHM_IDENTIFIER,
|
141
|
-
:PublicKey, CRYPT_BIT_BLOB
|
142
|
-
end
|
143
|
-
|
144
|
-
class CERT_INFO < FFI::Struct
|
145
|
-
layout :dwVersion, DWORD,
|
146
|
-
:SerialNumber, CRYPT_INTEGER_BLOB,
|
147
|
-
:SignatureAlgorithm, CRYPT_ALGORITHM_IDENTIFIER,
|
148
|
-
:Issuer, CRYPT_NAME_BLOB,
|
149
|
-
:NotBefore, FILETIME,
|
150
|
-
:NotAfter, FILETIME,
|
151
|
-
:Subject, CRYPT_NAME_BLOB,
|
152
|
-
:SubjectPublicKeyInfo, CERT_PUBLIC_KEY_INFO,
|
153
|
-
:IssuerUniqueId, CRYPT_BIT_BLOB,
|
154
|
-
:SubjectUniqueId, CRYPT_BIT_BLOB,
|
155
|
-
:cExtension, DWORD,
|
156
|
-
:rgExtension, CERT_EXTENSION
|
157
|
-
end
|
158
|
-
|
159
|
-
class CERT_CONTEXT < FFI::Struct
|
160
|
-
layout :dwCertEncodingType, DWORD,
|
161
|
-
:pbCertEncoded, BYTE,
|
162
|
-
:cbCertEncoded, DWORD,
|
163
|
-
:pCertInfo, CERT_INFO,
|
164
|
-
:hCertStore, HCERTSTORE
|
165
|
-
end
|
166
|
-
|
167
|
-
###############################################################################
|
168
|
-
# Windows Function
|
169
|
-
# To know description about below windows function
|
170
|
-
# Search Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa376560
|
171
|
-
###############################################################################
|
172
|
-
|
173
|
-
# To opens the most common system certificate store
|
174
|
-
safe_attach_function :CertOpenSystemStoreW, [HCRYPTPROV_LEGACY, LPCTSTR], HCERTSTORE
|
175
|
-
# To close the already open certificate store
|
176
|
-
safe_attach_function :CertCloseStore, [HCERTSTORE, DWORD], BOOL
|
177
|
-
# To create encoded certificate context
|
178
|
-
safe_attach_function :CertCreateCertificateContext, [DWORD, BYTE, DWORD], PCCERT_CONTEXT
|
179
|
-
# To retrieves certificates in a certificate store
|
180
|
-
safe_attach_function :CertEnumCertificatesInStore, [HCERTSTORE, PCCERT_CONTEXT], PCCERT_CONTEXT
|
181
|
-
# To get certificate name
|
182
|
-
safe_attach_function :CertGetNameStringW, [PCCERT_CONTEXT, DWORD, DWORD, LPVOID, LPTSTR, DWORD], DWORD
|
183
|
-
# To find all of the property identifiers for the specified certificate.
|
184
|
-
safe_attach_function :CertEnumCertificateContextProperties, [PCCERT_CONTEXT, DWORD], DWORD
|
185
|
-
# Clean up
|
186
|
-
safe_attach_function :CertFreeCertificateContext, [PCCERT_CONTEXT], BOOL
|
187
|
-
# Add certificate file in certificate store.
|
188
|
-
safe_attach_function :CertAddSerializedElementToStore, [HCERTSTORE, :pointer, DWORD, DWORD, DWORD, DWORD, LMSTR, LPVOID], BOOL
|
189
|
-
# Add certification to certification store - Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa376015(v=vs.85).aspx
|
190
|
-
safe_attach_function :CertAddEncodedCertificateToStore, [HCERTSTORE, DWORD, PWSTR, DWORD, INT_PTR, PCCERT_CONTEXT], BOOL
|
191
|
-
safe_attach_function :CertSerializeCertificateStoreElement, [PCCERT_CONTEXT, DWORD, :pointer, DWORD], BOOL
|
192
|
-
# Duplicates a certificate context by incrementing its reference count
|
193
|
-
safe_attach_function :CertDuplicateCertificateContext, [PCCERT_CONTEXT], PCCERT_CONTEXT
|
194
|
-
# Delete certification from certification store
|
195
|
-
safe_attach_function :CertDeleteCertificateFromStore, [PCCERT_CONTEXT], BOOL
|
196
|
-
# To retrieve specific certificates from certificate store
|
197
|
-
safe_attach_function :CertFindCertificateInStore, [HCERTSTORE, DWORD, DWORD, DWORD, LPVOID, PCCERT_CONTEXT], PCCERT_CONTEXT
|
198
|
-
|
199
|
-
safe_attach_function :PFXExportCertStoreEx, [HCERTSTORE, CRYPT_INTEGER_BLOB, LPCTSTR, LPVOID, DWORD], BOOL
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
1
|
+
#
|
2
|
+
# Author:: Nimisha Sharad (<nimisha.sharad@msystechnologies.com>)
|
3
|
+
# Copyright:: Copyright (c) 2017 Chef Software, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require "ffi"
|
20
|
+
|
21
|
+
module Win32
|
22
|
+
class Certstore
|
23
|
+
module Mixin
|
24
|
+
module Crypto
|
25
|
+
extend FFI::Library
|
26
|
+
|
27
|
+
ffi_lib "Crypt32"
|
28
|
+
ffi_convention :stdcall
|
29
|
+
|
30
|
+
# Attempts to use FFI's attach_function method to link a native Win32
|
31
|
+
# function into the calling module. If this fails a dummy method is
|
32
|
+
# defined which when called, raises a helpful exception to the end-user.
|
33
|
+
module FFI::Library
|
34
|
+
def safe_attach_function(win32_func, *args)
|
35
|
+
attach_function(win32_func.to_sym, *args)
|
36
|
+
rescue FFI::NotFoundError
|
37
|
+
define_method(win32_func.to_sym) do |*margs|
|
38
|
+
raise NotImplementedError, "This version of Windows does not implement the Win32 function [#{win32_func}]."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
###############################################
|
44
|
+
# Win32 API Constants
|
45
|
+
###############################################
|
46
|
+
|
47
|
+
CERT_CLOSE_STORE_CHECK_FLAG = 0
|
48
|
+
CERT_CLOSE_STORE_FORCE_FLAG = 1
|
49
|
+
|
50
|
+
# cert encoding flags.
|
51
|
+
CRYPT_ASN_ENCODING = 0x00000001
|
52
|
+
CRYPT_NDR_ENCODING = 0x00000002
|
53
|
+
X509_ASN_ENCODING = 0x00000001
|
54
|
+
X509_NDR_ENCODING = 0x00000002
|
55
|
+
PKCS_7_ASN_ENCODING = 0x00010000
|
56
|
+
PKCS_7_NDR_ENCODING = 0x00020000
|
57
|
+
PKCS_7_OR_X509_ASN_ENCODING = (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
|
58
|
+
|
59
|
+
# Certificate Display Format
|
60
|
+
CERT_NAME_EMAIL_TYPE = 1
|
61
|
+
CERT_NAME_RDN_TYPE = 2
|
62
|
+
CERT_NAME_ATTR_TYPE = 3
|
63
|
+
CERT_NAME_SIMPLE_DISPLAY_TYPE = 4
|
64
|
+
CERT_NAME_FRIENDLY_DISPLAY_TYPE = 5
|
65
|
+
CERT_NAME_DNS_TYPE = 6
|
66
|
+
CERT_NAME_URL_TYPE = 7
|
67
|
+
CERT_NAME_UPN_TYPE = 8
|
68
|
+
|
69
|
+
# Retrieve Certificates flag
|
70
|
+
CERT_FIND_SUBJECT_STR = 0x00080007
|
71
|
+
CERT_FIND_ISSUER_STR = 0x00080004
|
72
|
+
|
73
|
+
# List Certificates Flag
|
74
|
+
CERT_NAME_ISSUER_FLAG = 0x1
|
75
|
+
CERT_NAME_DISABLE_IE4_UTF8_FLAG = 0x00010000
|
76
|
+
CERT_NAME_SEARCH_ALL_NAMES_FLAG = 0x2
|
77
|
+
CERT_NAME_STR_ENABLE_PUNYCODE_FLAG = 0x00200000
|
78
|
+
|
79
|
+
# Define ffi pointer
|
80
|
+
HCERTSTORE = FFI::TypeDefs[:pointer]
|
81
|
+
HCRYPTPROV_LEGACY = FFI::TypeDefs[:pointer]
|
82
|
+
PCCERT_CONTEXT = FFI::TypeDefs[:pointer]
|
83
|
+
BYTE = FFI::TypeDefs[:pointer]
|
84
|
+
DWORD = FFI::TypeDefs[:uint32]
|
85
|
+
BLOB = FFI::TypeDefs[:ulong]
|
86
|
+
LPSTR = FFI::TypeDefs[:pointer]
|
87
|
+
LPCTSTR = FFI::TypeDefs[:pointer]
|
88
|
+
BOOL = FFI::TypeDefs[:bool]
|
89
|
+
INT_PTR = FFI::TypeDefs[:int]
|
90
|
+
LONG = FFI::TypeDefs[:long]
|
91
|
+
LPVOID = FFI::TypeDefs[:pointer]
|
92
|
+
LPTSTR = FFI::TypeDefs[:pointer]
|
93
|
+
LMSTR = FFI::TypeDefs[:pointer]
|
94
|
+
PWSTR = FFI::TypeDefs[:pointer]
|
95
|
+
LPFILETIME = FFI::TypeDefs[:pointer]
|
96
|
+
PCERT_INFO = FFI::TypeDefs[:pointer]
|
97
|
+
PCTL_USAGE = FFI::TypeDefs[:pointer]
|
98
|
+
PCTL_VERIFY_USAGE_PARA = FFI::TypeDefs[:pointer]
|
99
|
+
PCTL_VERIFY_USAGE_STATUS = FFI::TypeDefs[:pointer]
|
100
|
+
|
101
|
+
class FILETIME < FFI::Struct
|
102
|
+
layout :dwLowDateTime, DWORD,
|
103
|
+
:dwHighDateTime, DWORD
|
104
|
+
end
|
105
|
+
|
106
|
+
class CRYPT_INTEGER_BLOB < FFI::Struct
|
107
|
+
layout :cbData, DWORD, # Count, in bytes, of data
|
108
|
+
:pbData, :pointer # Pointer to data buffer
|
109
|
+
end
|
110
|
+
|
111
|
+
class CRYPT_NAME_BLOB < FFI::Struct
|
112
|
+
layout :cbData, DWORD, # Count, in bytes, of data
|
113
|
+
:pbData, :pointer # Pointer to data buffer
|
114
|
+
def initialize(str = nil)
|
115
|
+
super(nil)
|
116
|
+
if str
|
117
|
+
self[:pbData] = FFI::MemoryPointer.new(2, 128)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class CERT_EXTENSION < FFI::Struct
|
123
|
+
layout :pszObjId, LPTSTR,
|
124
|
+
:fCritical, BOOL,
|
125
|
+
:Value, CRYPT_INTEGER_BLOB
|
126
|
+
end
|
127
|
+
|
128
|
+
class CRYPT_BIT_BLOB < FFI::Struct
|
129
|
+
layout :cbData, DWORD,
|
130
|
+
:pbData, BYTE,
|
131
|
+
:cUnusedBits, DWORD
|
132
|
+
end
|
133
|
+
|
134
|
+
class CRYPT_ALGORITHM_IDENTIFIER < FFI::Struct
|
135
|
+
layout :pszObjId, LPSTR,
|
136
|
+
:Parameters, CRYPT_INTEGER_BLOB
|
137
|
+
end
|
138
|
+
|
139
|
+
class CERT_PUBLIC_KEY_INFO < FFI::Struct
|
140
|
+
layout :Algorithm, CRYPT_ALGORITHM_IDENTIFIER,
|
141
|
+
:PublicKey, CRYPT_BIT_BLOB
|
142
|
+
end
|
143
|
+
|
144
|
+
class CERT_INFO < FFI::Struct
|
145
|
+
layout :dwVersion, DWORD,
|
146
|
+
:SerialNumber, CRYPT_INTEGER_BLOB,
|
147
|
+
:SignatureAlgorithm, CRYPT_ALGORITHM_IDENTIFIER,
|
148
|
+
:Issuer, CRYPT_NAME_BLOB,
|
149
|
+
:NotBefore, FILETIME,
|
150
|
+
:NotAfter, FILETIME,
|
151
|
+
:Subject, CRYPT_NAME_BLOB,
|
152
|
+
:SubjectPublicKeyInfo, CERT_PUBLIC_KEY_INFO,
|
153
|
+
:IssuerUniqueId, CRYPT_BIT_BLOB,
|
154
|
+
:SubjectUniqueId, CRYPT_BIT_BLOB,
|
155
|
+
:cExtension, DWORD,
|
156
|
+
:rgExtension, CERT_EXTENSION
|
157
|
+
end
|
158
|
+
|
159
|
+
class CERT_CONTEXT < FFI::Struct
|
160
|
+
layout :dwCertEncodingType, DWORD,
|
161
|
+
:pbCertEncoded, BYTE,
|
162
|
+
:cbCertEncoded, DWORD,
|
163
|
+
:pCertInfo, CERT_INFO,
|
164
|
+
:hCertStore, HCERTSTORE
|
165
|
+
end
|
166
|
+
|
167
|
+
###############################################################################
|
168
|
+
# Windows Function
|
169
|
+
# To know description about below windows function
|
170
|
+
# Search Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa376560
|
171
|
+
###############################################################################
|
172
|
+
|
173
|
+
# To opens the most common system certificate store
|
174
|
+
safe_attach_function :CertOpenSystemStoreW, [HCRYPTPROV_LEGACY, LPCTSTR], HCERTSTORE
|
175
|
+
# To close the already open certificate store
|
176
|
+
safe_attach_function :CertCloseStore, [HCERTSTORE, DWORD], BOOL
|
177
|
+
# To create encoded certificate context
|
178
|
+
safe_attach_function :CertCreateCertificateContext, [DWORD, BYTE, DWORD], PCCERT_CONTEXT
|
179
|
+
# To retrieves certificates in a certificate store
|
180
|
+
safe_attach_function :CertEnumCertificatesInStore, [HCERTSTORE, PCCERT_CONTEXT], PCCERT_CONTEXT
|
181
|
+
# To get certificate name
|
182
|
+
safe_attach_function :CertGetNameStringW, [PCCERT_CONTEXT, DWORD, DWORD, LPVOID, LPTSTR, DWORD], DWORD
|
183
|
+
# To find all of the property identifiers for the specified certificate.
|
184
|
+
safe_attach_function :CertEnumCertificateContextProperties, [PCCERT_CONTEXT, DWORD], DWORD
|
185
|
+
# Clean up
|
186
|
+
safe_attach_function :CertFreeCertificateContext, [PCCERT_CONTEXT], BOOL
|
187
|
+
# Add certificate file in certificate store.
|
188
|
+
safe_attach_function :CertAddSerializedElementToStore, [HCERTSTORE, :pointer, DWORD, DWORD, DWORD, DWORD, LMSTR, LPVOID], BOOL
|
189
|
+
# Add certification to certification store - Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa376015(v=vs.85).aspx
|
190
|
+
safe_attach_function :CertAddEncodedCertificateToStore, [HCERTSTORE, DWORD, PWSTR, DWORD, INT_PTR, PCCERT_CONTEXT], BOOL
|
191
|
+
safe_attach_function :CertSerializeCertificateStoreElement, [PCCERT_CONTEXT, DWORD, :pointer, DWORD], BOOL
|
192
|
+
# Duplicates a certificate context by incrementing its reference count
|
193
|
+
safe_attach_function :CertDuplicateCertificateContext, [PCCERT_CONTEXT], PCCERT_CONTEXT
|
194
|
+
# Delete certification from certification store
|
195
|
+
safe_attach_function :CertDeleteCertificateFromStore, [PCCERT_CONTEXT], BOOL
|
196
|
+
# To retrieve specific certificates from certificate store
|
197
|
+
safe_attach_function :CertFindCertificateInStore, [HCERTSTORE, DWORD, DWORD, DWORD, LPVOID, PCCERT_CONTEXT], PCCERT_CONTEXT
|
198
|
+
|
199
|
+
safe_attach_function :PFXExportCertStoreEx, [HCERTSTORE, CRYPT_INTEGER_BLOB, LPCTSTR, LPVOID, DWORD], BOOL
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|