Skip to content

Instantly share code, notes, and snippets.

@piyushawasthi
Created January 30, 2018 10:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save piyushawasthi/d43776d6455a90b8469f261acba3356f to your computer and use it in GitHub Desktop.
Save piyushawasthi/d43776d6455a90b8469f261acba3356f to your computer and use it in GitHub Desktop.
Verify Certificate from certificate store
require 'chef'
require 'mixlib/shellout'
require 'ffi'
require "chef/win32/api"
require 'openssl'
module Cert
extend Chef::ReservedNames::Win32::API
extend FFI::Library
ffi_lib 'Crypt32'
###############################################
# Win32 API Constants
###############################################
CERT_CLOSE_STORE_CHECK_FLAG = 0
CERT_CLOSE_STORE_FORCE_FLAG = 1
# cert encoding flags.
CRYPT_ASN_ENCODING = 0x00000001
CRYPT_NDR_ENCODING = 0x00000002
X509_ASN_ENCODING = 0x00000001
X509_NDR_ENCODING = 0x00000002
PKCS_7_ASN_ENCODING = 0x00010000
PKCS_7_NDR_ENCODING = 0x00020000
PKCS_7_OR_X509_ASN_ENCODING = (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
# Certificate Display Format
CERT_NAME_EMAIL_TYPE = 1
CERT_NAME_RDN_TYPE = 2
CERT_NAME_ATTR_TYPE = 3
CERT_NAME_SIMPLE_DISPLAY_TYPE = 4
CERT_NAME_FRIENDLY_DISPLAY_TYPE = 5
CERT_NAME_DNS_TYPE = 6
CERT_NAME_URL_TYPE = 7
CERT_NAME_UPN_TYPE = 8
# Retrieve Certificates flag
CERT_FIND_SUBJECT_STR = 0x00080007
CERT_FIND_ISSUER_STR = 0x00080004
# List Certificates Flag
CERT_NAME_ISSUER_FLAG = 0x1
CERT_NAME_DISABLE_IE4_UTF8_FLAG = 0x00010000
CERT_NAME_SEARCH_ALL_NAMES_FLAG = 0x2
CERT_NAME_STR_ENABLE_PUNYCODE_FLAG = 0x00200000
# Define ffi pointer
HCERTSTORE = FFI::TypeDefs[:pointer]
HCRYPTPROV_LEGACY = FFI::TypeDefs[:pointer]
PCCERT_CONTEXT = FFI::TypeDefs[:pointer]
BYTE = FFI::TypeDefs[:pointer]
DWORD = FFI::TypeDefs[:uint32]
BLOB = FFI::TypeDefs[:ulong]
LPSTR = FFI::TypeDefs[:pointer]
LPCTSTR = FFI::TypeDefs[:pointer]
BOOL = FFI::TypeDefs[:bool]
INT_PTR = FFI::TypeDefs[:int]
LONG = FFI::TypeDefs[:long]
LPVOID = FFI::TypeDefs[:pointer]
LPTSTR = FFI::TypeDefs[:pointer]
LMSTR = FFI::TypeDefs[:pointer]
PWSTR = FFI::TypeDefs[:pointer]
PCERT_INFO = FFI::TypeDefs[:pointer]
class FILETIME < FFI::Struct
layout :dwLowDateTime, DWORD,
:dwHighDateTime, DWORD
end
class CRYPT_INTEGER_BLOB < FFI::Struct
layout :cbData, DWORD, # Count, in bytes, of data
:pbData, :pointer # Pointer to data buffer
end
class CERT_EXTENSION < FFI::Struct
layout :pszObjId, LPTSTR,
:fCritical, BOOL,
:Value, CRYPT_INTEGER_BLOB
end
class CRYPT_BIT_BLOB < FFI::Struct
layout :cbData, DWORD,
:pbData, BYTE,
:cUnusedBits, DWORD
end
class CRYPT_ALGORITHM_IDENTIFIER < FFI::Struct
layout :pszObjId, LPSTR,
:Parameters, CRYPT_INTEGER_BLOB
end
class CERT_PUBLIC_KEY_INFO < FFI::Struct
layout :Algorithm, CRYPT_ALGORITHM_IDENTIFIER,
:PublicKey, CRYPT_BIT_BLOB
end
class CERT_INFO < FFI::Struct
layout :dwVersion, DWORD,
:SerialNumber, CRYPT_INTEGER_BLOB,
:SignatureAlgorithm, CRYPT_ALGORITHM_IDENTIFIER,
:Issuer, CRYPT_INTEGER_BLOB,
:NotBefore, FILETIME,
:NotAfter, FILETIME,
:Subject, CRYPT_INTEGER_BLOB,
:SubjectPublicKeyInfo, CERT_PUBLIC_KEY_INFO,
:IssuerUniqueId, CRYPT_BIT_BLOB,
:SubjectUniqueId, CRYPT_BIT_BLOB,
:cExtension, DWORD,
:rgExtension, CERT_EXTENSION
end
###############################################################################
# Windows Function
# To know description about below windows function
# Search Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa376560
###############################################################################
# To opens the most common system certificate store
safe_attach_function :CertOpenSystemStoreW, [HCRYPTPROV_LEGACY, LPCTSTR], HCERTSTORE
# To close the already open certificate store
safe_attach_function :CertCloseStore, [HCERTSTORE, DWORD], BOOL
# To retrieve specific certificates from certificate store
safe_attach_function :CertFindCertificateInStore, [HCERTSTORE, DWORD, DWORD, DWORD, LPVOID, PCCERT_CONTEXT], PCCERT_CONTEXT
# The CertVerifyTimeValidity function verifies the time validity of a certificate
safe_attach_function :CertVerifyTimeValidity, [FILETIME, PCERT_INFO], LONG
end
##################################################
include Chef::Mixin::WideString
include Cert
store_handler = CertOpenSystemStoreW(nil, wstring("Root"))
# Expired
certificate_name = "Microsoft Authenticode(tm) Root Authority"
# Valid
certificate_name = "AddTrust External CA Root"
if ( !certificate_name.empty? && pCertContext = CertFindCertificateInStore(store_handler, X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_STR, certificate_name.to_wstring, nil) and not pCertContext.null? )
pTargetCertInfo = CERT_INFO.new(pCertContext)
case CertVerifyTimeValidity(nil, pTargetCertInfo)
when -1
puts "Certificate is not valid yet."
when 1
puts "Certificate is expired."
when 0
puts "Certificate's time is valid."
else
puts "Certificate time validity not matched."
end
end
CertCloseStore(store_handler, CERT_CLOSE_STORE_FORCE_FLAG)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment