在 SWI-Prolog 中打开并检查 Pem 文件
Opening and checking a Pem file in SWI-Prolog
我如何打开 Pem 文件来检查 a) 'Not before' 和 'Not after' 日期是否正确以及 b) pem 文件中是否存在到路由证书的证书链权威?
我试过:
:-use_module(library(http/http_client)).
url('http://fm4dd.com/openssl/source/PEM/certs/512b-rsa-example-cert.pem').
url_data(Url,D):-
http_get(Url,D,[to(string)]).
url_data1(Url,Certificate):-
http_get(Url,D,[to(stream(Stream))]),
load_certificate(Stream, Certificate),
close(Stream).
url_data/1
的工作原理是它 return 将 pem 文件作为字符串。但是 url_data1/1
不起作用。它旨在 return 每个证书作为术语列表。
*更新*
我有:
url_data1(Url,Certs):-
http_open(Url,Stream,[]),
all_certs(Stream,Certs),
forall(member(C,Certs),my_validate(C)),
close(Stream).
all_certs(Stream,[C1|Certs]):-
catch(load_certificate(Stream,C1),_,fail),
all_certs(Stream,Certs),!.
all_certs(_Stream,[]).
my_validate(C):-
memberchk(to_be_signed(Signed),C),
memberchk(key(Key),C),
memberchk(signature(Signature),C),
memberchk(signature_algorithm(A),C),
algo_code(A,Code),
rsa_verify(Key,Signed,Signature,[type(Code)]).
algo_code('RSA-SHA256',sha256).
algo_code('RSA-SHA1',sha1).
哪个失败了。什么是正确的论点?
您可以将 http_open/3
与 load_certificate/2
结合使用:
?- url(Url),
http_open(Url, Stream, []),
load_certificate(Stream, Certificate),
maplist(portray_clause, Certificate).
产量:
version(0).
notbefore(1345613214).
notafter(1503293214).
serial('0DFA').
subject(['C'='JP', 'ST'='Tokyo', 'O'='Frank4DD', 'CN'='www.example.com']).
hash("071CB94F0CC8514D024124708EE8B2687BD7D9D5").
signature("14B64CBB817933E671A4DA516FCB081D8D60ECBC18C7734759B1F22048BB61FAFC4DAD898DD121EBD5D8E5BAD6A636FD745083B60FC71DDF7DE52E817F45E09FE23E79EED73031C72072D9582E2AFE125A3445A119087C89475F4A95BE23214A5372DA2A052F2EC970F65BFAFDDFB431B2C14A9C062543A1E6B41E7F869B1640").
signature_algorithm('RSA-SHA1').
etc.
检查 issuer_name/1
元素以获得发行者。您可以再次使用 load_certificate/2
从文件中读取更多证书。
请注意,验证证书链的更典型方法是建立安全连接(通过 HTTPS),然后使用 ssl_peer_certificate/2
或 ssl_peer_certificate_chain/2
在流上获取对等证书和证书链。
要验证链,您必须验证 signature/1
字段,其中包含由相应颁发者签署的证书 to_be_signed/1
部分的数字签名。
您可以使用 library(crypto)
来验证签名。
我如何打开 Pem 文件来检查 a) 'Not before' 和 'Not after' 日期是否正确以及 b) pem 文件中是否存在到路由证书的证书链权威?
我试过:
:-use_module(library(http/http_client)).
url('http://fm4dd.com/openssl/source/PEM/certs/512b-rsa-example-cert.pem').
url_data(Url,D):-
http_get(Url,D,[to(string)]).
url_data1(Url,Certificate):-
http_get(Url,D,[to(stream(Stream))]),
load_certificate(Stream, Certificate),
close(Stream).
url_data/1
的工作原理是它 return 将 pem 文件作为字符串。但是 url_data1/1
不起作用。它旨在 return 每个证书作为术语列表。
*更新*
我有:
url_data1(Url,Certs):-
http_open(Url,Stream,[]),
all_certs(Stream,Certs),
forall(member(C,Certs),my_validate(C)),
close(Stream).
all_certs(Stream,[C1|Certs]):-
catch(load_certificate(Stream,C1),_,fail),
all_certs(Stream,Certs),!.
all_certs(_Stream,[]).
my_validate(C):-
memberchk(to_be_signed(Signed),C),
memberchk(key(Key),C),
memberchk(signature(Signature),C),
memberchk(signature_algorithm(A),C),
algo_code(A,Code),
rsa_verify(Key,Signed,Signature,[type(Code)]).
algo_code('RSA-SHA256',sha256).
algo_code('RSA-SHA1',sha1).
哪个失败了。什么是正确的论点?
您可以将 http_open/3
与 load_certificate/2
结合使用:
?- url(Url), http_open(Url, Stream, []), load_certificate(Stream, Certificate), maplist(portray_clause, Certificate).
产量:
version(0). notbefore(1345613214). notafter(1503293214). serial('0DFA'). subject(['C'='JP', 'ST'='Tokyo', 'O'='Frank4DD', 'CN'='www.example.com']). hash("071CB94F0CC8514D024124708EE8B2687BD7D9D5"). signature("14B64CBB817933E671A4DA516FCB081D8D60ECBC18C7734759B1F22048BB61FAFC4DAD898DD121EBD5D8E5BAD6A636FD745083B60FC71DDF7DE52E817F45E09FE23E79EED73031C72072D9582E2AFE125A3445A119087C89475F4A95BE23214A5372DA2A052F2EC970F65BFAFDDFB431B2C14A9C062543A1E6B41E7F869B1640"). signature_algorithm('RSA-SHA1'). etc.
检查 issuer_name/1
元素以获得发行者。您可以再次使用 load_certificate/2
从文件中读取更多证书。
请注意,验证证书链的更典型方法是建立安全连接(通过 HTTPS),然后使用 ssl_peer_certificate/2
或 ssl_peer_certificate_chain/2
在流上获取对等证书和证书链。
要验证链,您必须验证 signature/1
字段,其中包含由相应颁发者签署的证书 to_be_signed/1
部分的数字签名。
您可以使用 library(crypto)
来验证签名。