Revision | 526 (tree) |
---|---|
Time | 2020-11-07 06:30:22 |
Author | derekwildstar |
KRK.Rtl.Win.WinCrypt.pas
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
A função CryptGenKey foi corrigida
A função CryptGetUserKey foi corrigida
A constante CERT_SIGN_HASH_CNG_ALG_PROP_ID foi adicionada
KRK.Rtl.Win.WinCrypt.Utilities.pas
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Iniciada a correção da função XMLSign considerando que o algoritmo de assinatura não pode ser livremente escolhido
A alteração ainda não foi concluída
GetKeyContainerInfo agora é GetCertificateKeyContainerInfo
Criada a função GetCertificateSignatureAlgorithm
Criada a função GetKeyPair
Criada a função DeleteKeySet
Removidas referências parametrizadas a <SignatureMethod> nos templates
Outros ajustes que não sei como descrever
Contém erros!
@@ -97,7 +97,7 @@ | ||
97 | 97 | |
98 | 98 | TSignatureFormat = (sfNotSet, sfEnveloped, sfEnveloping); |
99 | 99 | TDigestAlgorithm = (daNotSet, daSHA1, daSHA224, daSHA256, daSHA384, daSHA512); |
100 | - TSignatureAlgorithm = (saNotSet, saDSASHA1, saDSASHA256, saRSASHA1, saRSASHA224, saRSASHA256, saRSASHA384, saRSASHA512, saECDSASHA1, saECDSASHA224, saECDSASHA256, saECDSASHA384, saECDSASHA512); | |
100 | + TSignatureAlgorithm = (saNotSet, saRSASHA1, saFromCertificate); | |
101 | 101 | |
102 | 102 | TWriteKeyInfo = (wkiKeyValue = KEYVALUE, wkiCertificates = CERTIFICATES, wkiPurge = PURGE); |
103 | 103 | TWriteKeyInfos = set of TWriteKeyInfo; |
@@ -132,6 +132,8 @@ | ||
132 | 132 | Encoding: String; |
133 | 133 | end; |
134 | 134 | |
135 | + TKeyPairType = (kptNotSet, kptKeyExchange, kptSignature); | |
136 | + | |
135 | 137 | //: Seleciona um certificado de acordo com os parâmetros especificados. |
136 | 138 | //: Use esta função para retornar um contexto de certificado (PCCERT_CONTEXT) ou |
137 | 139 | //: mostrar uma tela que lista os certificados disponíveis, dependendo da |
@@ -235,13 +237,27 @@ | ||
235 | 237 | // no url a seguir, principalmente a parte que fala das funções que usam |
236 | 238 | // CRYPT_KEY_PROV_INFO talvez elas sejam um atalho |
237 | 239 | // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_key_prov_info |
238 | -function GetKeyContainerInfo(ACertificateContext: PCCERT_CONTEXT; out ACryptKeyProvInfo: PCryptKeyProvInfo): Boolean; | |
240 | +function GetCertificateKeyContainerInfo(ACertificateContext: PCCERT_CONTEXT; out ACryptKeyProvInfo: PCryptKeyProvInfo): Boolean; | |
241 | +//: Obtém o nome do algoritmo de assinatura do certificado. | |
242 | +function GetCertificateSignatureAlgorithm(ACertificateContext: PCCERT_CONTEXT): String; | |
239 | 243 | //: Assina um arquivo qualquer usando o formato XML, tal como especificado em |
240 | 244 | //: https://www.w3.org/TR/xmldsig-core2/. Esta função requer que a biblioteca |
241 | 245 | //: MSXML5 esteja registrada |
242 | 246 | function XMLSign(const AParams: TXMLSignParams): TXMLSignReturn; |
247 | +// Isso parece não usar MSXML5!!! | |
248 | +// https://docs.microsoft.com/en-us/windows/win32/seccrypto/cryptography-functions#cryptxml-functions | |
243 | 249 | function XMLVerifySign(const AParams: TXMLVerifySignParams; out AReturn: TXMLVerifySignReturn): Boolean; |
244 | 250 | |
251 | +// Leia no site abaixo um exemplo de como obter uma chave de sessão e gerar seu hash, talvez seja possível criar chaves (senhas?) aleatorias, algo do que eu fiz manualmente no DefinedCrypt pde ser feito de forma mais sofisticada aqui | |
252 | +// https://docs.microsoft.com/en-us/windows/win32/seccrypto/example-c-program-creating-and-hashing-a-session-key | |
253 | + | |
254 | +// Obtém o par de chaves a partir do contêiner de chaves no provedor do tipo | |
255 | +// indicado. Caso não haja o contêiner o achave especificada, o contêiner será | |
256 | +// criado e/ou a chave especificada e assim um handle para essa chave será | |
257 | +// retornado. Esse handle precisa ser destruído com CryptDestroyKey | |
258 | +function GetKeyPair(AKeyContainerName: String; AProviderName: String; AProviderType: Word; AKeyPairType: TKeyPairType; AKeyPairCreationFlags: DWORD; out AKeyPair: HCRYPTKEY): Boolean; | |
259 | +procedure DeleteKeySet(AKeyContainerName: String; AProviderName: String; AProviderType: Cardinal); | |
260 | + | |
245 | 261 | implementation |
246 | 262 | |
247 | 263 | uses |
@@ -257,7 +273,7 @@ | ||
257 | 273 | '<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">'#13#10 + |
258 | 274 | ' <SignedInfo>'#13#10 + |
259 | 275 | ' <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />'#13#10 + |
260 | - ' <SignatureMethod Algorithm="<:SIGNATUREALGORITHM:>" />'#13#10 + //http://www.w3.org/2000/09/xmldsig#rsa-sha1 | |
276 | + ' <SignatureMethod />'#13#10 + | |
261 | 277 | ' <Reference URI="<:URI:>">'#13#10 + |
262 | 278 | ' <Transforms>'#13#10 + |
263 | 279 | ' <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />'#13#10 + |
@@ -275,7 +291,7 @@ | ||
275 | 291 | '<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">'#13#10 + |
276 | 292 | ' <SignedInfo>'#13#10 + |
277 | 293 | ' <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />'#13#10 + |
278 | - ' <SignatureMethod Algorithm="<:SIGNATUREALGORITHM:>" />'#13#10 + //http://www.w3.org/2000/09/xmldsig#rsa-sha1 | |
294 | + ' <SignatureMethod />'#13#10 + | |
279 | 295 | ' <Reference URI="#<:URI:>">'#13#10 + |
280 | 296 | ' <DigestMethod Algorithm="<:DIGESTALGORITHM:>" />'#13#10 + //http://www.w3.org/2000/09/xmldsig#sha1 |
281 | 297 | ' <DigestValue />'#13#10 + |
@@ -678,6 +694,13 @@ | ||
678 | 694 | // Obtém o provedor a partir do contexto do certificado usado para |
679 | 695 | // assinar. O nome da função é estranho e não parece indicar que ela |
680 | 696 | // serve pra isso, mas foi pra isso que eu a usei, e deu certo. |
697 | + | |
698 | + // The CryptAcquireCertificatePrivateKey function obtains the private | |
699 | + // key for a certificate. This function is used to obtain access to a | |
700 | + // user's private key when the user's certificate is available, but | |
701 | + // the handle of the user's key container is not available. This | |
702 | + // function can only be used by the owner of a private key and not by | |
703 | + // any other user. | |
681 | 704 | if not CryptAcquireCertificatePrivateKey(CertificateContext |
682 | 705 | ,0 |
683 | 706 | ,nil |
@@ -709,7 +732,7 @@ | ||
709 | 732 | // Retorna a chave em format BLOB (Little-Endian) |
710 | 733 | if not CryptGetUserKey(CryptProviderHandle |
711 | 734 | ,KeySpec |
712 | - ,KeysHandle) then | |
735 | + ,@KeysHandle) then | |
713 | 736 | raise EAdvApi.Create(GetLastError,'CryptGetUserKey@GetSignature: Não foi possível obter o handle para as chaves do CSP') |
714 | 737 | else |
715 | 738 | try |
@@ -1826,40 +1849,65 @@ | ||
1826 | 1849 | } |
1827 | 1850 | *) |
1828 | 1851 | |
1829 | -function GetKeyContainerInfo(ACertificateContext: PCCERT_CONTEXT; out ACryptKeyProvInfo: PCryptKeyProvInfo): Boolean; | |
1852 | +function GetCertificateKeyContainerInfo(ACertificateContext: PCCERT_CONTEXT; out ACryptKeyProvInfo: PCryptKeyProvInfo): Boolean; | |
1830 | 1853 | var |
1831 | - CryptKeyProvInfoSize: DWORD; | |
1854 | + InfoSize: DWORD; | |
1832 | 1855 | begin |
1833 | 1856 | Result := False; |
1834 | 1857 | ACryptKeyProvInfo := nil; |
1835 | - CryptKeyProvInfoSize := 0; | |
1858 | + InfoSize := 0; | |
1836 | 1859 | |
1837 | 1860 | if CertGetCertificateContextProperty(ACertificateContext |
1838 | 1861 | ,CERT_KEY_PROV_INFO_PROP_ID |
1839 | 1862 | ,nil |
1840 | - ,@CryptKeyProvInfoSize) then | |
1863 | + ,@InfoSize) then | |
1841 | 1864 | begin |
1842 | - ACryptKeyProvInfo := AllocMem(CryptKeyProvInfoSize); | |
1865 | + ACryptKeyProvInfo := AllocMem(InfoSize); | |
1843 | 1866 | |
1844 | 1867 | if CertGetCertificateContextProperty(ACertificateContext |
1845 | 1868 | ,CERT_KEY_PROV_INFO_PROP_ID |
1846 | 1869 | ,ACryptKeyProvInfo |
1847 | - ,@CryptKeyProvInfoSize) then | |
1870 | + ,@InfoSize) then | |
1848 | 1871 | Result := True; |
1849 | 1872 | end; |
1850 | 1873 | end; |
1851 | 1874 | |
1875 | +function GetCertificateSignatureAlgorithm(ACertificateContext: PCCERT_CONTEXT): String; | |
1876 | +var | |
1877 | + InfoData: PChar; | |
1878 | + InfoSize: DWORD; | |
1879 | +begin | |
1880 | + Result := ''; | |
1881 | + | |
1882 | + if CertGetCertificateContextProperty(ACertificateContext | |
1883 | + ,CERT_SIGN_HASH_CNG_ALG_PROP_ID | |
1884 | + ,nil | |
1885 | + ,@InfoSize) then | |
1886 | + begin | |
1887 | + GetMem(InfoData,InfoSize); | |
1888 | + try | |
1889 | + if CertGetCertificateContextProperty(ACertificateContext | |
1890 | + ,CERT_SIGN_HASH_CNG_ALG_PROP_ID | |
1891 | + ,InfoData | |
1892 | + ,@InfoSize) then | |
1893 | + begin | |
1894 | + Result := InfoData; | |
1895 | + end; | |
1896 | + finally | |
1897 | + FreeMem(InfoData); | |
1898 | + end; | |
1899 | + end; | |
1900 | + | |
1901 | +end; | |
1902 | + | |
1852 | 1903 | function XMLSign(const AParams: TXMLSignParams): TXMLSignReturn; |
1853 | 1904 | var |
1854 | 1905 | PreparedTemplate: String; |
1855 | 1906 | SignatureTemplate: IXMLDOMDocument3; |
1856 | 1907 | InputXML: IXMLDOMDocument3; |
1857 | - CertificateContext: PCCERT_CONTEXT; | |
1858 | - KeyContainerInfo: PCryptKeyProvInfo; | |
1859 | - XMLDigitalSignature: IXMLDigitalSignature; // No futuro, olhe XMLDigitalSignatureEx | |
1860 | - XMLDSigKey: IXMLDSigKey; | |
1861 | 1908 | ContentsData: PByte; |
1862 | 1909 | ContentsSize: DWORD; |
1910 | + CertificateContext: PCCERT_CONTEXT; | |
1863 | 1911 | // - /////////////////////////////////////////////////////////////////////////// |
1864 | 1912 | procedure PrepareTemplate(aTemplate: String); |
1865 | 1913 | var |
@@ -1903,25 +1951,6 @@ | ||
1903 | 1951 | else |
1904 | 1952 | raise Exception.Create('O formato da assinatura não foi especificado'); |
1905 | 1953 | |
1906 | - case Aparams.SignatureAlgorithm of | |
1907 | - saDSASHA1: Aux := 'http://www.w3.org/2000/09/xmldsig#dsa-sha1'; | |
1908 | - saDSASHA256: Aux := 'http://www.w3.org/2009/xmldsig11#dsa-sha256'; | |
1909 | - saRSASHA1: Aux := 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'; | |
1910 | - saRSASHA224: Aux := 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha224'; | |
1911 | - saRSASHA256: Aux := 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'; | |
1912 | - saRSASHA384: Aux := 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384'; | |
1913 | - saRSASHA512: Aux := 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'; | |
1914 | - saECDSASHA1: Aux := 'http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1'; | |
1915 | - saECDSASHA224: Aux := 'http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224'; | |
1916 | - saECDSASHA256: Aux := 'http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256'; | |
1917 | - saECDSASHA384: Aux := 'http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384'; | |
1918 | - saECDSASHA512: Aux := 'http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512'; | |
1919 | - else | |
1920 | - raise Exception.Create('Não foi selecionado o algorítmo de hash da assinatura'); | |
1921 | - end; | |
1922 | - | |
1923 | - PreparedTemplate := StringReplace(PreparedTemplate,'<:SIGNATUREALGORITHM:>',Aux,[rfReplaceAll]); | |
1924 | - | |
1925 | 1954 | case AParams.DigestAlgorithm of |
1926 | 1955 | daSHA1: Aux := 'http://www.w3.org/2000/09/xmldsig#sha1'; |
1927 | 1956 | daSHA224: Aux := 'http://www.w3.org/2001/04/xmldsig-more#sha224'; |
@@ -1994,7 +2023,7 @@ | ||
1994 | 2023 | |
1995 | 2024 | if Assigned(KeyInfo) then |
1996 | 2025 | begin |
1997 | - X509Data := KeyInfo.selectSingleNode('X509Data'); | |
2026 | + X509Data := KeyInfo.selectSingleNode('ds:X509Data'); | |
1998 | 2027 | // A partir deste ponto nós filhos de <KeyInfo> serão selecionados, |
1999 | 2028 | // criados, adicionados e/ou complementados. Ao criar um novo nó, por |
2000 | 2029 | // padrão, o seu namespace é "em branco". Como <KeyInfo> está dentro de |
@@ -2015,7 +2044,7 @@ | ||
2015 | 2044 | if not Assigned(X509Data) then |
2016 | 2045 | X509Data := KeyInfo.appendChild(AXMLDocument.createNode(NODE_ELEMENT,'X509Data',SIGNATURENS)); |
2017 | 2046 | |
2018 | - X509Certificate := X509Data.selectSingleNode('X509Certificate'); | |
2047 | + X509Certificate := X509Data.selectSingleNode('ds:X509Certificate'); | |
2019 | 2048 | |
2020 | 2049 | if not Assigned(X509Certificate) then |
2021 | 2050 | begin |
@@ -2049,6 +2078,10 @@ | ||
2049 | 2078 | end; |
2050 | 2079 | end; |
2051 | 2080 | // - /////////////////////////////////////////////////////////////////////////// |
2081 | +var | |
2082 | + XMLDigitalSignature: IXMLDigitalSignatureEx; | |
2083 | + XMLDSigKey: IXMLDSigKeyEx; | |
2084 | + KPI: PCryptKeyProvInfo; | |
2052 | 2085 | begin |
2053 | 2086 | ZeroMemory(@Result,SizeOf(TXMLSignReturn)); |
2054 | 2087 | // Variável que vai conter o XML final, com o template aplicado + o conteúdo a |
@@ -2149,35 +2182,73 @@ | ||
2149 | 2182 | // <Signature>, usa-se "ds:Signature" |
2150 | 2183 | InputXML.setProperty('SelectionNamespaces', 'xmlns:ds="http://www.w3.org/2000/09/xmldsig#"'); |
2151 | 2184 | // Seleciona um certificado de acordo com as opções informadas |
2152 | - if SelectCertificate(AParams.SelectCertificateParams,CertificateContext) and GetKeyContainerInfo(CertificateContext,KeyContainerInfo) then | |
2153 | - try | |
2154 | - XMLDigitalSignature := CoMXDigitalSignature50.Create; | |
2155 | - XMLDigitalSignature.signature := InputXML.selectSingleNode('//ds:Signature'); | |
2156 | - // Abaixo, createKeyFromCSP vai usar informações obtidas a partir do | |
2157 | - // certificado informado a fim de criar as chaves necessárias para a | |
2158 | - // assinatura, entretanto, a geração das chaves não precisa ser baseada no | |
2159 | - // certificado. createKeyFromCSP precisa receber em seu primeiro parâmetro | |
2160 | - // um tipo de CSP que apenas pode ser um, de dois valores possíveis: | |
2161 | - // PROV_DSS_DH (13) ou PROV_RSA_FULL (1). O segundo parâmetro desta função | |
2162 | - // precisa receber o nome de um CSP do tipo indicado no primeiro | |
2163 | - // parâmetro. Já o terceiro parâmetro precisa receber o nome de um | |
2164 | - // contêiner de chaves. Esse nome precisa ser um nome válido dentro do CSP | |
2165 | - // informado. Para obter os nomes de contêineres de chaves de um CSP use a | |
2166 | - // função GetProviderKeyContainerNames | |
2167 | - XMLDSigKey := XMLDigitalSignature.createKeyFromCSP(KeyContainerInfo.dwProvType,KeyContainerInfo.pwszProvName,KeyContainerInfo.pwszContainerName,0); | |
2185 | + if SelectCertificate(AParams.SelectCertificateParams,CertificateContext) then | |
2186 | + begin | |
2187 | + XMLDigitalSignature := IXMLDigitalSignatureEx(CoMXDigitalSignature50.Create); | |
2188 | + XMLDigitalSignature.signature := InputXML.selectSingleNode('//ds:Signature'); | |
2189 | + // Leia isso: https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms754613(v=vs.85) | |
2190 | + // Não precisa da linha abaixo quando se usa createKeyFromCertContext | |
2168 | 2191 | |
2169 | - if Assigned(XMLDSigKey) then | |
2170 | - begin | |
2171 | - if Assigned(XMLDigitalSignature.sign(XMLDSigKey, WriteKeyInfos)) then | |
2172 | - ReturnAdjustedXML | |
2173 | - else | |
2174 | - raise Exception.Create('Não foi possível assinar'); | |
2175 | - end | |
2192 | + Usar a funcao abaixo para obter o handle do store do certificado.AParams | |
2193 | + Aparentemente hcertstore é um store que só tem um certificado e não é o | |
2194 | + certstore "real". use o handle do store onde o certificado está para ver se | |
2195 | + vai precisar adicionar o certificado manualmente. A intenção é tentar | |
2196 | + inserir todos os certificados existentes no store também, e | |
2197 | + | |
2198 | + CertOpenStore() | |
2199 | + | |
2200 | + XMLDigitalSignature.setStoreHandle(CertificateContext.hCertStore); | |
2201 | + | |
2202 | +// case AParams.SignatureAlgorithm of | |
2203 | +// saRSASHA1: ; | |
2204 | +// saFromCertificate: ; | |
2205 | +// else | |
2206 | +// raise Exception.Create('O algoritmo de assinatura não foi informado'); | |
2207 | +// end; | |
2208 | + | |
2209 | + // O algoritmo de assinatura depende do certificado, exclusivamente, quando | |
2210 | + // se assina. O certificado tem uma propriedade chamada "Algoritmo de hash de | |
2211 | + // assinatura", e é ele que será usado na hora de assinar no nó SignatureMethod, não importa qual o algoritmo selecionado | |
2212 | + //IXMLDigitalSignatureEx(XMLDigitalSignature).createKeyFromCertContext(CertificateContext,XMLDSigKey); | |
2213 | + | |
2214 | + // Ao usar a forma abaixo, o algoritmo de hash assinatura aparentemente pode ser diferente daquele informado no certificado | |
2215 | + // createKeyFromCSP exige PROV_RSA_FULL ou PROV_DSS_DH | |
2216 | + // O que é um conteiner de chaves? https://stackoverflow.com/questions/2528186/what-exactly-is-a-key-container | |
2217 | + // https://docs.microsoft.com/pt-br/windows/win32/seccrypto/example-c-program-creating-a-key-container-and-generating-keys?redirectedfrom=MSDN | |
2218 | + //var y: String := 'SafeSign Standard Cryptographic Service Provider'; | |
2219 | + | |
2220 | +// Escolha o melhor tipo 1 e crie/selecione as chaves nele neste ponto do codigo | |
2221 | +// talvez seja bom criar as chaves e logo em seguida destruir? | |
2222 | +// Conteiners de chave do tipo 1 aqui só criam SHA-1 no algoritmo de assinatura | |
2223 | +// para usar o do certificado, o codigo é outro | |
2224 | +// | |
2225 | +// crie uma opção pra isso que será ou sha-1 (quando cria as chaves aqui) | |
2226 | +// ou de acordo com o certificado (pra pegar o que o certificado tiver | |
2227 | +// remova as opções de hash de chave então | |
2228 | + | |
2229 | + //XMLDSigKey := IXMLDSigKeyEx(IXMLDigitalSignatureEx(XMLDigitalSignature).createKeyFromCSP(PROV_RSA_FULL,y,'Meu conteiner de chaves',0)); | |
2230 | + | |
2231 | + // Aqui podemos obter XMLDSigKey a partir do CSP do certificado | |
2232 | + // KPI contém informações sobre o conteiner de chaves associado ao | |
2233 | + // certificado. Este contêiner de chaves, contém chaves que foram emitidas | |
2234 | + // pela entidade de certificação do certificado em questão, portanto XMLDSigKey vai se referir diretamente ao certificado utilizado | |
2235 | + GetCertificateKeyContainerInfo(CertificateContext,KPI); | |
2236 | + // createKeyFromCSP apenas trabalha com PROV_RSA_FULL e PROV_DSS_DH, ambos só trabalham com SHA-1, por isso o algoritmo da assinatura digital no xml final é SHA-1 | |
2237 | + XMLDSigKey := IXMLDSigKeyEx(IXMLDigitalSignatureEx(XMLDigitalSignature).createKeyFromCSP(KPI.dwProvType | |
2238 | + ,KPI.pwszProvName | |
2239 | + ,KPI.pwszContainerName | |
2240 | + ,0)); | |
2241 | + | |
2242 | + if Assigned(XMLDSigKey) then | |
2243 | + begin | |
2244 | + if Assigned(XMLDigitalSignature.sign(XMLDSigKey, WriteKeyInfos)) then | |
2245 | + ReturnAdjustedXML | |
2176 | 2246 | else |
2177 | - raise Exception.Create('Não foi possível criar a chave a partir do CSP'); | |
2178 | - finally | |
2179 | - FreeMem(KeyContainerInfo); | |
2180 | - end; | |
2247 | + raise Exception.Create('Não foi possível assinar'); | |
2248 | + end | |
2249 | + else | |
2250 | + raise Exception.Create('Não foi possível obter a chave a partir do certficado digital escolhido'); | |
2251 | + end; | |
2181 | 2252 | end; |
2182 | 2253 | |
2183 | 2254 | // O url abaixo tem um exemplo que valida a cadeia de certificados. Isso pode |
@@ -2268,4 +2339,100 @@ | ||
2268 | 2339 | end; |
2269 | 2340 | end; |
2270 | 2341 | |
2342 | +function GetKeyPair(AKeyContainerName: String; AProviderName: String; AProviderType: Word; AKeyPairType: TKeyPairType; AKeyPairCreationFlags: DWORD; out AKeyPair: HCRYPTKEY): Boolean; | |
2343 | +var | |
2344 | + KeyContainerHandle: HCRYPTPROV; | |
2345 | + KeySpec: DWORD; | |
2346 | +begin | |
2347 | + Result := False; | |
2348 | + KeyContainerHandle := 0; | |
2349 | + AKeyPair := 0; | |
2350 | + | |
2351 | + if Trim(AKeyContainerName) = '' then | |
2352 | + raise Exception.Create('Favor informar o nome do contêiner de chaves'); | |
2353 | + | |
2354 | + if Trim(AProviderName) = '' then | |
2355 | + raise Exception.Create('Favor informar o nome do provedor criptográfico (CSP)'); | |
2356 | + | |
2357 | + case AKeyPairType of | |
2358 | + kptKeyExchange: KeySpec := AT_KEYEXCHANGE; | |
2359 | + kptSignature: KeySpec := AT_SIGNATURE; | |
2360 | + else | |
2361 | + raise Exception.Create('O tipo de par de chaves não foi informado'); | |
2362 | + end; | |
2363 | + | |
2364 | + // Na primeira execução, tenta adquirir o contexto para o contêiner de | |
2365 | + // chaves especificado em AKeyContainerName, mas como este contêiner não | |
2366 | + // existe, ele será criado, apenas se o erro tiver sido NTE_BAD_KEYSET ou | |
2367 | + // NTE_KEYSET_NOT_DEF. Caso não seja possível criar o contêiner de chaves, uma | |
2368 | + // exceção será levantada. Mais detalhes em https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta | |
2369 | + if not CryptAcquireContext(@KeyContainerHandle | |
2370 | + ,PChar(AKeyContainerName) | |
2371 | + ,PChar(AProviderName) | |
2372 | + ,AProviderType | |
2373 | + ,0) then | |
2374 | + begin | |
2375 | + if (GetLastError = Cardinal(NTE_BAD_KEYSET)) or (GetLastError = Cardinal(NTE_KEYSET_NOT_DEF)) then | |
2376 | + begin | |
2377 | + if not CryptAcquireContext(@KeyContainerHandle | |
2378 | + ,PChar(AKeyContainerName) | |
2379 | + ,PChar(AProviderName) | |
2380 | + ,AProviderType | |
2381 | + ,CRYPT_NEWKEYSET) then | |
2382 | + raise EWinCrypt.Create(GetLastError,'Não foi possível criar um novo contêiner de chaves usando os dados informados'); | |
2383 | + end | |
2384 | + else | |
2385 | + raise EWinCrypt.Create(GetLastError,'Falha ao obter o manipulador para o contêiner de chaves especificado'); | |
2386 | + end; | |
2387 | + | |
2388 | + // Se o fluxo chegar aqui o contêiner de chaves foi selecionado/criado e seu | |
2389 | + // contexto (handle) encontra-se em "KeyContainerHandle" } | |
2390 | + | |
2391 | + if KeyContainerHandle > 0 then | |
2392 | + try | |
2393 | + // Na primeira execução, tenta obter um handle para um par de chaves a partir | |
2394 | + // de KeyContainerHandle. Caso o contêiner esteja vazio, o erro será | |
2395 | + // NTE_NO_KEY e um par de chaves para assinatura digital será criado e | |
2396 | + // colocado no contêiner identificado por KeyContainerHandle e, finalmente, um | |
2397 | + // handle será retornado em AKeyPair | |
2398 | + if not CryptGetUserKey(KeyContainerHandle | |
2399 | + ,KeySpec | |
2400 | + ,@AKeyPair) then | |
2401 | + begin | |
2402 | + if GetLastError = Cardinal(NTE_NO_KEY) then | |
2403 | + begin | |
2404 | + if not CryptGenKey(KeyContainerHandle | |
2405 | + ,KeySpec | |
2406 | + ,AKeyPairCreationFlags | |
2407 | + ,@AKeyPair) then | |
2408 | + raise EWinCrypt.Create(GetLastError,'Não foi possível criar um novo par de chaves'); | |
2409 | + end | |
2410 | + else | |
2411 | + raise EWinCrypt.Create(GetLastError,'Falha ao obter o manipulador para o par de chaves'); | |
2412 | + end; | |
2413 | + | |
2414 | + Result := True; | |
2415 | + finally | |
2416 | + CryptReleaseContext(KeyContainerHandle,0); | |
2417 | + end; | |
2418 | +end; | |
2419 | + | |
2420 | +procedure DeleteKeySet(AKeyContainerName: String; AProviderName: String; AProviderType: Cardinal); | |
2421 | +var | |
2422 | + KeyContainerHandle: HCRYPTPROV; | |
2423 | +begin | |
2424 | + if Trim(AKeyContainerName) = '' then | |
2425 | + raise Exception.Create('Favor informar o nome do contêiner de chaves'); | |
2426 | + | |
2427 | + if Trim(AProviderName) = '' then | |
2428 | + raise Exception.Create('Favor informar o nome do provedor criptográfico (CSP)'); | |
2429 | + | |
2430 | + if not CryptAcquireContext(@KeyContainerHandle | |
2431 | + ,PChar(AKeyContainerName) | |
2432 | + ,PChar(AProviderName) | |
2433 | + ,AProviderType | |
2434 | + ,CRYPT_DELETEKEYSET) then | |
2435 | + raise EWinCrypt.Create(GetLastError,'Não foi possível excluir o contêiner de chaves especificado'); | |
2436 | +end; | |
2437 | + | |
2271 | 2438 | end. |
@@ -1576,8 +1576,7 @@ | ||
1576 | 1576 | function CryptReleaseContext(hProv: HCRYPTPROV; dwFlags: DWORD): BOOL; winapi; |
1577 | 1577 | |
1578 | 1578 | {$EXTERNALSYM CryptGenKey} |
1579 | -function CryptGenKey(hProv: HCRYPTPROV; Algid: ALG_ID; dwFlags: DWORD; | |
1580 | - var phKey: HCRYPTKEY): BOOL; winapi; | |
1579 | +function CryptGenKey(hProv: HCRYPTPROV; Algid: ALG_ID; dwFlags: DWORD; phKey: PHCRYPTKEY): BOOL; winapi; | |
1581 | 1580 | |
1582 | 1581 | {$EXTERNALSYM CryptDeriveKey} |
1583 | 1582 | function CryptDeriveKey(hProv: HCRYPTPROV; Algid: ALG_ID; hBaseData: HCRYPTHASH; dwFlags: DWORD; phKey: PHCRYPTKEY): BOOL; winapi; |
@@ -1611,8 +1610,7 @@ | ||
1611 | 1610 | pbBuffer: PBYTE): BOOL; winapi; |
1612 | 1611 | |
1613 | 1612 | {$EXTERNALSYM CryptGetUserKey} |
1614 | -function CryptGetUserKey(hProv: HCRYPTPROV; dwKeySpec: DWORD; | |
1615 | - out phUserKey: HCRYPTKEY): BOOL; winapi; | |
1613 | +function CryptGetUserKey(hProv: HCRYPTPROV; dwKeySpec: DWORD; phUserKey: PHCRYPTKEY): BOOL; winapi; | |
1616 | 1614 | |
1617 | 1615 | {$EXTERNALSYM CryptExportKey} |
1618 | 1616 | function CryptExportKey(hKey: HCRYPTKEY; hExpKey: HCRYPTKEY; dwBlobType: DWORD; dwFlags: DWORD; pbData: PBYTE; dwDataLen: PDWORD): BOOL; winapi; |
@@ -10561,6 +10559,8 @@ | ||
10561 | 10559 | CERT_ROOT_PROGRAM_NAME_CONSTRAINTS_PROP_ID = 84; |
10562 | 10560 | {$EXTERNALSYM CERT_FIRST_RESERVED_PROP_ID} |
10563 | 10561 | CERT_FIRST_RESERVED_PROP_ID = 85; |
10562 | + {$EXTERNALSYM CERT_SIGN_HASH_CNG_ALG_PROP_ID} | |
10563 | + CERT_SIGN_HASH_CNG_ALG_PROP_ID = 89; | |
10564 | 10564 | |
10565 | 10565 | {$EXTERNALSYM CERT_LAST_RESERVED_PROP_ID} |
10566 | 10566 | CERT_LAST_RESERVED_PROP_ID = $00007FFF; |
@@ -0,0 +1,247 @@ | ||
1 | +Id do Tipo Nome do provedor criptográfico (CSP) Implementação | |
2 | +---------- ---------------------------------------------------------------- ---------------------------------------- | |
3 | + 1 Microsoft Base Cryptographic Provider v1.0 SW | |
4 | + 13 Microsoft Base DSS and Diffie-Hellman Cryptographic Provider SW | |
5 | + 3 Microsoft Base DSS Cryptographic Provider SW | |
6 | + 1 Microsoft Base Smart Card Crypto Provider HW+SW+MX+RM | |
7 | + 18 Microsoft DH SChannel Cryptographic Provider SW | |
8 | + 1 Microsoft Enhanced Cryptographic Provider v1.0 SW | |
9 | + 13 Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider SW | |
10 | + 24 Microsoft Enhanced RSA and AES Cryptographic Provider SW | |
11 | + 12 Microsoft RSA SChannel Cryptographic Provider SW | |
12 | + 1 Microsoft Strong Cryptographic Provider SW | |
13 | + 1 SafeSign Standard Cryptographic Service Provider HW+SW+MX+RM | |
14 | + 24 SafeSign Standard RSA and AES Cryptographic Service Provider HW+SW+MX+RM | |
15 | +---------------------------------------------------------------------------------------------------------------------- | |
16 | +HW = Hardware, SW = Software, MX = HW+SW, RM = Mídia Removível, UK = Desconhecido | |
17 | + | |
18 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
19 | +Microsoft Base Cryptographic Provider v1.0 (Tipo 1) | |
20 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
21 | +ID do algoritmo Nome Bits Tipo | |
22 | +--------------- --------------- ---- --------- | |
23 | +00006602h RC2 40 Encrypt | |
24 | +00006801h RC4 40 Encrypt | |
25 | +00006601h DES 56 Encrypt | |
26 | +00008004h SHA-1 160 Hash | |
27 | +00008001h MD2 128 Hash | |
28 | +00008002h MD4 128 Hash | |
29 | +00008003h MD5 128 Hash | |
30 | +00008008h SSL3 SHAMD5 288 Hash | |
31 | +00008005h MAC 0 Hash | |
32 | +00002400h RSA_SIGN 512 Signature | |
33 | +0000A400h RSA_KEYX 512 Exchange | |
34 | +00008009h HMAC 0 Hash | |
35 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
36 | +Microsoft Base DSS and Diffie-Hellman Cryptographic Provider (Tipo 13) | |
37 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
38 | +ID do algoritmo Nome Bits Tipo | |
39 | +--------------- --------------- ---- --------- | |
40 | +0000660Ch CYLINK MEK 40 Encrypt | |
41 | +00006602h RC2 40 Encrypt | |
42 | +00006801h RC4 40 Encrypt | |
43 | +00006601h DES 56 Encrypt | |
44 | +00008004h SHA-1 160 Hash | |
45 | +00008003h MD5 128 Hash | |
46 | +00002200h DSA_SIGN 1024 Signature | |
47 | +0000AA01h DH_KEYX 512 Exchange | |
48 | +0000AA02h DH_KEYX 512 Exchange | |
49 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
50 | +Microsoft Base DSS Cryptographic Provider (Tipo 3) | |
51 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
52 | +ID do algoritmo Nome Bits Tipo | |
53 | +--------------- --------------- ---- --------- | |
54 | +00008004h SHA-1 160 Hash | |
55 | +00008003h MD5 128 Hash | |
56 | +00002200h DSA_SIGN 1024 Signature | |
57 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
58 | +Microsoft Base Smart Card Crypto Provider (Tipo 1) | |
59 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
60 | +ID do algoritmo Nome Bits Tipo | |
61 | +--------------- --------------- ---- --------- | |
62 | +00006602h RC2 128 Encrypt | |
63 | +00006801h RC4 128 Encrypt | |
64 | +00006601h DES 56 Encrypt | |
65 | +00006609h 3DES TWO KEY 112 Encrypt | |
66 | +00006603h 3DES 168 Encrypt | |
67 | +00008004h SHA-1 160 Hash | |
68 | +0000800Ch SHA-256 256 Hash | |
69 | +0000800Dh SHA-384 384 Hash | |
70 | +0000800Eh SHA-512 512 Hash | |
71 | +00008001h MD2 128 Hash | |
72 | +00008002h MD4 128 Hash | |
73 | +00008003h MD5 128 Hash | |
74 | +00008008h SSL3 SHAMD5 288 Hash | |
75 | +00008005h MAC 0 Hash | |
76 | +00002400h RSA_SIGN 2048 Signature | |
77 | +0000A400h RSA_KEYX 2048 Exchange | |
78 | +00008009h HMAC 0 Hash | |
79 | +0000660Eh AES 128 128 Encrypt | |
80 | +0000660Fh AES 192 192 Encrypt | |
81 | +00006610h AES 256 256 Encrypt | |
82 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
83 | +Microsoft DH SChannel Cryptographic Provider (Tipo 18) | |
84 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
85 | +ID do algoritmo Nome Bits Tipo | |
86 | +--------------- --------------- ---- --------- | |
87 | +0000660Ch CYLINK MEK 40 Encrypt | |
88 | +00006602h RC2 40 Encrypt | |
89 | +00006801h RC4 40 Encrypt | |
90 | +00006601h DES 56 Encrypt | |
91 | +00006609h 3DES TWO KEY 112 Encrypt | |
92 | +00006603h 3DES 168 Encrypt | |
93 | +00008004h SHA-1 160 Hash | |
94 | +00008003h MD5 128 Hash | |
95 | +00002200h DSA_SIGN 1024 Signature | |
96 | +0000AA01h DH_KEYX 512 Exchange | |
97 | +0000AA02h DH_KEYX 512 Exchange | |
98 | +00004C01h SSL3 MASTER 384 Unknown | |
99 | +00004C06h TLS1 MASTER 384 Unknown | |
100 | +00004C02h SCH MASTER HASH 0 Unknown | |
101 | +00004C03h SCH MAC KEY 0 Unknown | |
102 | +00004C07h SCH ENC KEY 0 Unknown | |
103 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
104 | +Microsoft Enhanced Cryptographic Provider v1.0 (Tipo 1) | |
105 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
106 | +ID do algoritmo Nome Bits Tipo | |
107 | +--------------- --------------- ---- --------- | |
108 | +00006602h RC2 128 Encrypt | |
109 | +00006801h RC4 128 Encrypt | |
110 | +00006601h DES 56 Encrypt | |
111 | +00006609h 3DES TWO KEY 112 Encrypt | |
112 | +00006603h 3DES 168 Encrypt | |
113 | +00008004h SHA-1 160 Hash | |
114 | +00008001h MD2 128 Hash | |
115 | +00008002h MD4 128 Hash | |
116 | +00008003h MD5 128 Hash | |
117 | +00008008h SSL3 SHAMD5 288 Hash | |
118 | +00008005h MAC 0 Hash | |
119 | +00002400h RSA_SIGN 1024 Signature | |
120 | +0000A400h RSA_KEYX 1024 Exchange | |
121 | +00008009h HMAC 0 Hash | |
122 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
123 | +Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider (Tipo 13) | |
124 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
125 | +ID do algoritmo Nome Bits Tipo | |
126 | +--------------- --------------- ---- --------- | |
127 | +0000660Ch CYLINK MEK 40 Encrypt | |
128 | +00006602h RC2 128 Encrypt | |
129 | +00006801h RC4 128 Encrypt | |
130 | +00006601h DES 56 Encrypt | |
131 | +00006609h 3DES TWO KEY 112 Encrypt | |
132 | +00006603h 3DES 168 Encrypt | |
133 | +00008004h SHA-1 160 Hash | |
134 | +00008003h MD5 128 Hash | |
135 | +00002200h DSA_SIGN 1024 Signature | |
136 | +0000AA01h DH_KEYX 1024 Exchange | |
137 | +0000AA02h DH_KEYX 1024 Exchange | |
138 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
139 | +Microsoft Enhanced RSA and AES Cryptographic Provider (Tipo 24) | |
140 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
141 | +ID do algoritmo Nome Bits Tipo | |
142 | +--------------- --------------- ---- --------- | |
143 | +00006602h RC2 128 Encrypt | |
144 | +00006801h RC4 128 Encrypt | |
145 | +00006601h DES 56 Encrypt | |
146 | +00006609h 3DES TWO KEY 112 Encrypt | |
147 | +00006603h 3DES 168 Encrypt | |
148 | +00008004h SHA-1 160 Hash | |
149 | +0000800Ch SHA-256 256 Hash | |
150 | +0000800Dh SHA-384 384 Hash | |
151 | +0000800Eh SHA-512 512 Hash | |
152 | +00008001h MD2 128 Hash | |
153 | +00008002h MD4 128 Hash | |
154 | +00008003h MD5 128 Hash | |
155 | +00008008h SSL3 SHAMD5 288 Hash | |
156 | +00008005h MAC 0 Hash | |
157 | +00002400h RSA_SIGN 1024 Signature | |
158 | +0000A400h RSA_KEYX 1024 Exchange | |
159 | +00008009h HMAC 0 Hash | |
160 | +0000660Eh AES 128 128 Encrypt | |
161 | +0000660Fh AES 192 192 Encrypt | |
162 | +00006610h AES 256 256 Encrypt | |
163 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
164 | +Microsoft RSA SChannel Cryptographic Provider (Tipo 12) | |
165 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
166 | +ID do algoritmo Nome Bits Tipo | |
167 | +--------------- --------------- ---- --------- | |
168 | +0000660Eh AES 128 128 Encrypt | |
169 | +00006610h AES 256 256 Encrypt | |
170 | +00006602h RC2 128 Encrypt | |
171 | +00006801h RC4 128 Encrypt | |
172 | +00006601h DES 56 Encrypt | |
173 | +00006609h 3DES TWO KEY 112 Encrypt | |
174 | +00006603h 3DES 168 Encrypt | |
175 | +00008004h SHA-1 160 Hash | |
176 | +00008003h MD5 128 Hash | |
177 | +00008008h SSL3 SHAMD5 288 Hash | |
178 | +00008005h MAC 0 Hash | |
179 | +0000A400h RSA_KEYX 1024 Exchange | |
180 | +00008009h HMAC 0 Hash | |
181 | +00004C05h SSL2 MASTER 40 Unknown | |
182 | +00004C01h SSL3 MASTER 384 Unknown | |
183 | +00004C06h TLS1 MASTER 384 Unknown | |
184 | +00004C02h SCH MASTER HASH 0 Unknown | |
185 | +00004C03h SCH MAC KEY 0 Unknown | |
186 | +00004C07h SCH ENC KEY 0 Unknown | |
187 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
188 | +Microsoft Strong Cryptographic Provider (Tipo 1) | |
189 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
190 | +ID do algoritmo Nome Bits Tipo | |
191 | +--------------- --------------- ---- --------- | |
192 | +00006602h RC2 128 Encrypt | |
193 | +00006801h RC4 128 Encrypt | |
194 | +00006601h DES 56 Encrypt | |
195 | +00006609h 3DES TWO KEY 112 Encrypt | |
196 | +00006603h 3DES 168 Encrypt | |
197 | +00008004h SHA-1 160 Hash | |
198 | +00008001h MD2 128 Hash | |
199 | +00008002h MD4 128 Hash | |
200 | +00008003h MD5 128 Hash | |
201 | +00008008h SSL3 SHAMD5 288 Hash | |
202 | +00008005h MAC 0 Hash | |
203 | +00002400h RSA_SIGN 1024 Signature | |
204 | +0000A400h RSA_KEYX 1024 Exchange | |
205 | +00008009h HMAC 0 Hash | |
206 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
207 | +SafeSign Standard Cryptographic Service Provider (Tipo 1) | |
208 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
209 | +ID do algoritmo Nome Bits Tipo | |
210 | +--------------- --------------- ---- --------- | |
211 | +00008004h SHA-1 160 Hash | |
212 | +00008002h MD4 128 Hash | |
213 | +00008003h MD5 128 Hash | |
214 | +00006602h RC2 128 Encrypt | |
215 | +00006801h RC4 128 Encrypt | |
216 | +00006601h DES 56 Encrypt | |
217 | +00006609h 3DES TWO KEY 112 Encrypt | |
218 | +00006603h 3DES 168 Encrypt | |
219 | +00008008h SSL3 SHAMD5 288 Hash | |
220 | +00008005h MAC 0 Hash | |
221 | +00002400h RSA_SIGN 1024 Signature | |
222 | +0000A400h RSA_KEYX 1024 Exchange | |
223 | +00008009h HMAC 0 Hash | |
224 | +0000800Ch SHA-256 256 Hash | |
225 | +0000800Dh SHA-384 384 Hash | |
226 | +0000800Eh SHA-512 512 Hash | |
227 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
228 | +SafeSign Standard RSA and AES Cryptographic Service Provider (Tipo 24) | |
229 | +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | |
230 | +ID do algoritmo Nome Bits Tipo | |
231 | +--------------- --------------- ---- --------- | |
232 | +00008004h SHA-1 160 Hash | |
233 | +00008002h MD4 128 Hash | |
234 | +00008003h MD5 128 Hash | |
235 | +00006602h RC2 128 Encrypt | |
236 | +00006801h RC4 128 Encrypt | |
237 | +00006601h DES 56 Encrypt | |
238 | +00006609h 3DES TWO KEY 112 Encrypt | |
239 | +00006603h 3DES 168 Encrypt | |
240 | +00008008h SSL3 SHAMD5 288 Hash | |
241 | +00008005h MAC 0 Hash | |
242 | +00002400h RSA_SIGN 1024 Signature | |
243 | +0000A400h RSA_KEYX 1024 Exchange | |
244 | +00008009h HMAC 0 Hash | |
245 | +0000800Ch SHA-256 256 Hash | |
246 | +0000800Dh SHA-384 384 Hash | |
247 | +0000800Eh SHA-512 512 Hash | |
\ No newline at end of file |
@@ -27,6 +27,7 @@ | ||
27 | 27 | EDITCertificatePassword: TEdit; |
28 | 28 | Button1: TButton; |
29 | 29 | procedure CBBXProviderTypesChange(Sender: TObject); |
30 | + procedure Button1Click(Sender: TObject); | |
30 | 31 | private |
31 | 32 | function GetSelectCertificateParams: TSelectCertificateParams; |
32 | 33 | { Private declarations } |
@@ -71,7 +72,7 @@ | ||
71 | 72 | implementation |
72 | 73 | |
73 | 74 | uses |
74 | - KRK.Rtl.Win.WinCrypt, KRK.Rtl.Win.WinCrypt.Utilities; | |
75 | + KRK.Rtl.Win.WinCrypt, KRK.Rtl.Win.WinCrypt.Utilities, UDAMOPrincipal; | |
75 | 76 | |
76 | 77 | {$R *.dfm} |
77 | 78 |
@@ -93,6 +94,12 @@ | ||
93 | 94 | |
94 | 95 | { TFRAMSelecionarCertificado } |
95 | 96 | |
97 | +procedure TFRAMSelecionarCertificado.Button1Click(Sender: TObject); | |
98 | +begin | |
99 | + if DAMOPrincipal.OPDICarregarArquivoPFX.Execute then | |
100 | + EDITCertificateFile.Text := DAMOPrincipal.OPDICarregarArquivoPFX.FileName; | |
101 | +end; | |
102 | + | |
96 | 103 | procedure TFRAMSelecionarCertificado.CBBXProviderTypesChange(Sender: TObject); |
97 | 104 | begin |
98 | 105 | LoadCSPNames; |