I'm trying to read public cert using dig command as:
dig <domain> -t CERT
which will come back as something like:
;; ANSWER SECTION:
domain. 3600 IN CERT PKIX 54727 RSASHA1 MIIFfTCCBGWgAwIBAgIQCTinFRnGvxrlJ4zqeWKf/TANBgkqhkiG9w0B AQsFADB/MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEg MB4GA1UEChMXTmV4dGdlbiBIZWFsdGhjYXJlIEluYy4xOTA3BgNVBAMT ME5leHRnZW4gSGVhbHRoY2FyZSBEaXJlY3QgU2VjdXJlIE1lc3NhZ2lu ZyBDQSBHMjAeFw0yMjAzMDEwMDAwMDBaFw0yNDAyMjkyMzU5NTlaMGkx CzAJBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazERMA8GA1UEBxMI TmV3IFlvcmsxFjAUBgNVBAoTDUhlYWx0aGl4LCBJbmMxHDAaBgNVBAMT E2RpcmVjdC5oZWFsdGhpeC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IB DwAwggEKAoIBAQCj0VULvmE0VY0yU27696Lo1PGXk4bzPjwQANn0xtTp i13zc0fgWSHDMaDBuF6lRjw9uzIhXXxsakYVPhQjm1BrpBfnRLWbrm9c XHpvlumbSc/oGGZf/k7UotaAQwwUmbvBxaq4lyIID7qZMLZ6HssbNeys jEvHRfBXIs1lohEZgwQdrM/MnNLF63rqY7Ymh2qJUhHuu4qGKJO8RiVf gH4Qly8zAaBMlQ/XevvKPdPPtGyf923Hk7LABHta6WtaPCEgazYBjVmq SKL5mYaNHXYNjMRFe4dRH7e7hYaLmcWNdcMXFvOttYNCYM1YsFqAGOAL iGA5mm/dsomiDB9atdXHAgMBAAGjggIJMIICBTAfBgNVHSMEGDAWgBRW JSd4pIqHpJ781l5+fKpIP7aOOzAdBgNVHQ4EFgQU7aKfWKxg3rF+/eta 788DoC6i+r4wHgYDVR0RBBcwFYITZGlyZWN0LmhlYWx0aGl4Lm9yZzAO BgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwQwgakGA1Ud HwSBoTCBnjBNoEugSYZHaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL05l eHRnZW5IZWFsdGhjYXJlRGlyZWN0U2VjdXJlTWVzc2FnaW5nQ0FHMi5j cmwwTaBLoEmGR2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9OZXh0Z2Vu SGVhbHRoY2FyZURpcmVjdFNlY3VyZU1lc3NhZ2luZ0NBRzIuY3JsMDQG A1UdIAQtMCswDQYLKwYBBAGCwVsAAgAwDAYKKwYBBAGCwVsBAzAMBgor BgEEAYLBWwIBMIGNBggrBgEFBQcBAQSBgDB+MCQGCCsGAQUFBzABhhho dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wVgYIKwYBBQUHMAKGSmh0dHA6 Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9OZXh0Z2VuSGVhbHRoY2FyZURp cmVjdFNlY3VyZU1lc3NhZ2luZ0NBRzIuY3J0MAwGA1UdEwEB/wQCMAAw DQYJKoZIhvcNAQELBQADggEBADXqYelrcmLRV0olDpe1IpBfDoR5bxYy nvGmkrI/a2Wa1ZqbaVPsR3KevaDwKk/osXNIdcc1MbTsA6m1Lc0otJZd IlSn3YjzYZHwJqwzeL4OxYwJs8Dytdlxa3c6UYRtKNeT0FU8cKtQoXo2 3N9WG21UwoUwIfU0k86tX5saTqeUYgy2q4FWFIdjzCnL6+MKsEtpzKay AM6p96SUKLfBaUYMaHeFgQbkR9g/kcgQY89HtckzuOZwtYdEfuOlY/0Y dnzX+mmCA3FvKNj06oChiRNJeBOD3gbkFWTm0SJqRz61ciSssqvFTB/M vY2EVuDKUikwgfjlJnic7cj60TJrBFE=
My question is how can I get that cert in a PEM format so then can transfer it to the human readable like an ouput from openssl X509 to text.
Related
How do I open a Pem file to check a) That the 'Not before' and 'Not after' dates are okay and b) That there is a chain of certs in the pem file to a route certificate authority?
I have tried:
:-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 works in that it returns the pem file as a string. But url_data1/1 does not work. It is intended to return each certificate(s) as a list of terms.
* Update *
I have:
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).
Which fails. What are the correct arguments?
You can use http_open/3 in combination with load_certificate/2:
?- url(Url),
http_open(Url, Stream, []),
load_certificate(Stream, Certificate),
maplist(portray_clause, Certificate).
Yielding:
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.
Check the issuer_name/1 element to obtain the issuer. You can use load_certificate/2 again to read further certificates from the file.
Note that a much more typical way to validate the certificate chain is to establish a secure connection (via HTTPS), and then to use ssl_peer_certificate/2 or ssl_peer_certificate_chain/2 on the stream to obtain the peer certificate and certificate chain.
To validate the chain, you must verify the signature/1 fields, which contain the digital signatures of the to_be_signed/1 portions of the certificate, signed by the respective issuer.
You can use library(crypto) to verify the signatures.
I have a .pem file which will successfully connect to my website via the --cert parameter of curl. I then converted that to a der file:
openssl x509 -inform PEM -outform DER -in client.pem -out cert.der
Then I loaded that cert.der into my project and I'm now trying to use that with Alamofire, following the example on their homepage:
let serverTrustPolicy = ServerTrustPolicy.PinCertificates(
certificates: ServerTrustPolicy.certificatesInBundle(),
validateCertificateChain: true,
validateHost: true
)
let policyManager = ServerTrustPolicyManager(policies: ["my.domain.com" : serverTrustPolicy])
manager = Alamofire.Manager(configuration: configuration, serverTrustPolicyManager: policyManager)
manager.request(.GET, url, parameters: params, encoding: .URLEncodedInURL, headers: nil)
.authenticate(usingCredential: credential)
.validate()
.responseJSON {
When that runs though it just fails and I get a 'cancelled' as the error's localizedDescription, which is what Alamofire does when authentication fails.
What am I doing wrong?
The Alamofire cert pinning logic does not currently support this use case. It is only designed to handle cert and public key pinning, not client certificates used to authenticate with the server. This is something we could support in the future if this is a common use case.
With that said, I'm assuming in this case you are receiving a NSURLAuthenticationChallenge with a protection space that has an authentication method of type .NSURLAuthenticationMethodClientCertificate. In these cases, you need to evaluate the host of the challenge, then create an NSURLCredential using the credentialWithIdentity:certificates:persistence: API. By passing this credential off to the completion handler, the client certificate should be sent to the server to authenticate the connection. More info can be found here.
Client certificate authentication (NSURLAuthenticationMethodClientCertificate) requires the system identity and all certificates needed to authenticate with the server. Create an NSURLCredential object with credentialWithIdentity:certificates:persistence:.
I've never actually had a need to use this type of authentication before. You'll need to override the auth challenge SessionDelegate closure using the task override closure to get this working.
I'd like to know if this example is enough to provide certificate pinning with libcurl:
http://curl.haxx.se/libcurl/c/cacertinmem.html
because I have found that curl also allows http://curl.haxx.se/libcurl/c/CURLOPT_PINNEDPUBLICKEY.html
Since I'll be using a self-signed certificate and only trust on it I don't know if it's truly necessary to pinn it too.
resume: Can the connection be compromised if I only add my certificate (self-signed) to the x509 certificate store like the example? do I need to add extra checks? do I need to use the CURLOPT_PINNEDPUBLICKEY option?
Thanks.
You can find another example in the implementation of the new curl option in git 2.8 (March 2016):
See commit aeff8a6 (15 Feb 2016) by Christoph Egger (siccegge).
(Merged by Junio C Hamano -- gitster -- in commit e79112d, 24 Feb 2016)
http: implement public key pinning
Add the http.pinnedpubkey configuration option for public key pinning. It allows any string supported by libcurl -- base64(sha256(pubkey)) or filename of the full public key.
If cURL does not support pinning (is too old) output a warning to the user.
The git config man page mentions:
http.pinnedpubkey:
Public key of the https service.
It may either be the filename of a PEM or DER encoded public key file or a string starting with 'sha256//' followed by the base64 encoded sha256 hash of the public key.
See also libcurl 'CURLOPT_PINNEDPUBLICKEY'.
git will exit with an error if this option is set but not supported by cURL.
With Git 2.34 (Q4 2021), HTTPS error handling is updated when it comes to SSL certificate pinning:
See commit 3e8084f (24 Sep 2021) by Ævar Arnfjörð Bjarmason (avar).
(Merged by Junio C Hamano -- gitster -- in commit 97492aa, 11 Oct 2021)
http: check CURLE_SSL_PINNEDPUBKEYNOTMATCH when emitting errors
Signed-off-by: Ævar Arnfjörð Bjarmason
Change the error shown when a http.pinnedPubKey doesn't match to point the http.pinnedPubKey variable added in aeff8a6 ("http: implement public key pinning", 2016-02-15, Git v2.8.0-rc0 -- merge listed in batch #8), e.g.:
git -c http.pinnedPubKey=sha256/someNonMatchingKey ls-remote https://github.com/git/git.git
fatal: unable to access 'https://github.com/git/git.git/' with http.pinnedPubkey configuration: SSL: public key does not match pinned public key!
Before this we'd emit the exact same thing without the " with http.pinnedPubkey configuration".
The advantage of doing this is that we're going to get a translated message (everything after the ":" is hardcoded in English in libcurl), and we've got a reference to the git-specific configuration variable that is causing the error.
Unfortunately we can't test this easily, as there are no tests that require https:// in the test suite, and t/lib-httpd.sh doesn't know how to set up such tests.
See this thread for the start of a discussion about what it would take to have divergent "t/lib-httpd/apache.conf" test setups.
I have windows c++ project.
Need to implement both ssl client and server on top of existing winsock code.
I tried with openssl but it seems too messy. I assume there is nicer/shorter/cleaner/faster way implementeing this than openssl..
Im thankful for any suggestions..
You can use Windows built-in SSL stuff -- SChannel . Searching Google fo "SChannel SSL" would give you plenty of information (though SChannel itself is poorly documented and not easy to comprehend).
On the other hand, OpenSSL is not messy once you study the source code of some project, that uses OpenSSL.
Acctually .. After some time spent with openssl hacking I wouldnt say its that messy :)
In case anyone anytime needs to add ssl to existing winsock code:
existing winsock code was like this:
0: sockett.Listen etc....
1: sockett.Accept(client, .....
2: recv(client , ...)
3: send(client , .....)
well in short if you want to implement SSL here..
delete lines 2 and 3 :) and add:
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
SSL_CTX *tlsctx;
SSL *ssl;
tlsctx = SSL_CTX_new( SSLv23_method());
// search google : generate self signed certificate openssl
SSL_CTX_use_certificate_file(tlsctx, "ssl\\server1.crt" , SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(tlsctx, "ssl\\server1.key", SSL_FILETYPE_PEM);
ssl = SSL_new(tlsctx);
SSL_set_fd(ssl, client);
SSL_accept(ssl);
/* instaed recv SSL_read(ssl, ....*/
/* instaed send SSL_write(ssl, ....*/
/* not 100% sure Sleep and shutdown/free/close are entirely correct here but in my code works fine */
Sleep(3000);
SSL_shutdown(ssl);
SSL_free(ssl);
SSL_CTX_free(tlsctx);
shutdown(client, SD_BOTH);
Sleep(10);
closesocket(client);
For testing:
in command line run:
openssl s_client -host localhost -port <PORT>
I'm trying to figure out how to use the self compiled OpenSSL API to load an existing X.509 certificate (.crt) which I have included in Xcode's project structure.
I need a X509 object (from OpenSSL x509.h) which should be created/loaded from an existing file. Including the header works fine but I really can't find a way to load an existing certificate... There are sooo many methods in the x509.h but no sufficient documentation.
Thanks,
Chris
If you've read the character data into a char* s, something like
BIO* bio = BIO_new_mem_buf((void*)s, -1);
X509* cert = 0;
PEM_read_bio_X509(bio, &cert, 0, NULL);
...
X509_free(cert);
BIO_free(bio);