Add certs test

This commit is contained in:
Maciej Szlosarczyk 2019-05-24 14:18:46 +03:00
parent 23487ab663
commit eed763844a
No known key found for this signature in database
GPG key ID: 41D62D42D3B0D765
5 changed files with 217 additions and 0 deletions

View file

@ -1 +1,48 @@
-module(certs).
-include_lib("public_key/include/public_key.hrl").
-export([read_pem_certificate/1, get_subject_from_otp_certificate/1,
get_common_name_from_subject/1, certificate_to_pem/1,
read_der_certificate/1]).
%% Read certificate from the wire and return back an otp type record
read_der_certificate(Der) ->
Certificate = public_key:pkix_decode_cert(Der, otp),
Certificate.
%% Take an otp record and convert it into a string that can be set into HTTP
%% header SSL_CLIENT_CERT.
certificate_to_pem(Certificate) ->
PemEntry = {'Certificate', Certificate, not_encrypted},
PemString = public_key:pem_encode([PemEntry]),
binary:replace(PemString, <<"\n">>, <<" ">>, [global]).
%% Read only a specific type of certificate, otherwise fail.
get_subject_from_otp_certificate(Certificate) when is_record(Certificate, 'OTPCertificate') ->
Subject = Certificate#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.subject,
Subject.
%% Take a subject rdnSequence that can be set into
%% HTTP header SSL_CLIENT_S_DN_CN.
get_common_name_from_subject(Subject) ->
CommonName = ?'id-at-commonName',
{_Type, Field} = get_field_from_subject(Subject, CommonName),
Field.
%% Only used for local development test, is not required for the application.
read_pem_certificate(PathToCert) ->
{ok, PemBin} = file:read_file(PathToCert),
PemEntries = public_key:pem_decode(PemBin),
{value, CertEntry} = lists:keysearch('Certificate', 1, PemEntries),
{_, DerCert, _} = CertEntry,
Decoded = public_key:pkix_decode_cert(DerCert, otp),
Decoded.
get_field_from_subject({rdnSequence, Attributes}, Field) ->
FlatList = lists:flatten(Attributes),
ValidAttrs = lists:filter(fun (X) ->
X#'AttributeTypeAndValue'.type =:= Field
end, FlatList),
Attribute = lists:last(ValidAttrs),
Attribute#'AttributeTypeAndValue'.value.

View file

@ -0,0 +1,13 @@
-module(certs_SUITE).
-include_lib("common_test/include/ct.hrl").
-export([all/0]).
-export([run_eunit/1]).
all() -> [run_eunit].
%% Run Unit tests.
%% Todo: these should be property tests, not unit tests.
run_eunit(_Config) ->
ok = eunit:test(certs_tests).

View file

@ -0,0 +1,70 @@
-module(certs_tests).
-include_lib("eunit/include/eunit.hrl").
-include_lib("public_key/include/public_key.hrl").
-define(exampleCertFile, "fixtures/epp-proxy-test.crt.pem").
read_der_certificate_test() ->
PemEntries = public_key:pem_decode(certificate_pem()),
{value, CertEntry} = lists:keysearch('Certificate', 1, PemEntries),
{_, DerCert, _} = CertEntry,
Certificate = certs:read_der_certificate(DerCert),
?assert(is_record(Certificate, 'OTPCertificate')).
get_subject_from_otp_certificate_test() ->
Certificate = test_certificate(),
Subject = certs:get_subject_from_otp_certificate(Certificate),
{rdnSequence, ListOfAttributes} = Subject.
get_common_name_from_subject_test() ->
Certificate = test_certificate(),
Subject = certs:get_subject_from_otp_certificate(Certificate),
CommonName = certs:get_common_name_from_subject(Subject),
?assertEqual(<<"Epp Proxy Test">>, CommonName).
test_certificate() ->
PemEntries = public_key:pem_decode(certificate_pem()),
{value, CertEntry} = lists:keysearch('Certificate', 1, PemEntries),
{_, DerCert, _} = CertEntry,
Decoded = public_key:pkix_decode_cert(DerCert, otp),
Decoded.
%% Contents from fixtures/epp-proxy-test.crt.pem file
certificate_pem() ->
<<"-----BEGIN CERTIFICATE-----
MIIGWzCCBEOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgaoxCzAJBgNVBAYTAkVF
MREwDwYDVQQIDAhIYXJqdW1hYTEQMA4GA1UEBwwHVGFsbGlubjEjMCEGA1UECgwa
RWVzdGkgSW50ZXJuZXRpIFNpaHRhc3V0dXMxLzAtBgNVBAMMJk1hY2llaidzIGRl
dmVsb3BtZW50IGNlcnRpZmljYXRlIChFSVMpMSAwHgYJKoZIhvcNAQkBFhFoZWxs
b0BpbnRlcm5ldC5lZTAeFw0xOTA1MjMxMjUwMzFaFw0yMDA1MjIxMjUwMzFaMIGp
MQswCQYDVQQGEwJFRTERMA8GA1UECAwISGFyanVtYWExIzAhBgNVBAoMGkVlc3Rp
IEludGVybmV0aSBTaWh0YXN1dHVzMSMwIQYDVQQLDBpFUFAgUHJveHkgdGVzdCBj
ZXJ0aWZpY2F0ZTEXMBUGA1UEAwwORXBwIFByb3h5IFRlc3QxJDAiBgkqhkiG9w0B
CQEWFWVwcC1wcm94eUBpbnRlcm5ldC5lZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
ADCCAgoCggIBAMQalaRFIgknGeQ5iuoBju+cviOksq85azQRIwDaxwwjpFwmRwt2
smPa/0GMyG3/FBGNpUBtb+0ngVMCw5h4aUeWhs9Y9d1kMqaEgpdLm0hWpUIIqOMO
wQpHugPQGJiz75Y4tIUbdazODTvEChDNPZ7Ut8jVzsoRFIgPV4abcoqTqD0wNYZb
TQ0MzOulB2PsxzKrT9MzWkdyju3FYtDxXRGKP3vXC3YhN4EXLqoDzMU51NoYQcPc
Fk5j+1aQKXfNwJcLEvHGlHce9MIEakl5sJt+u8REmp43uy//DNa7mzACfu4xHAW+
heuH+xhEZAT40oxFi0Goa2rhMjz7hx5GM8KPFvJ0vlkR74pRnz1/XNqpx5PundYY
RK0swk+E+z3oFqClsjFiBVZQSPnYdGhid3qDaSqTsVO4G07rzh54SrBm7AsU8CQF
45OOngr1razw5jKnWH6qzNLFKcZBchOSmW31ZpTqfbol6UhThEM6qZr5Dsk+QZbd
kVZ5v3YZs72HL5Fxn/Ix5WOL886fSBOOHyg9rkFoypXZxfyZZehbhY3alszqJFbj
bJ4f+tt2+ObCbkUiN3huP+i+41l+eIBobtsaQhtdzp/44KWR5u4kk2OexO4oZPFN
futAsemo/sxU8E9KvjS02j2zIXTNyV/8Axp30LhHFQvey8QtNbhM2YClAgMBAAGj
gYkwgYYwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwLAYJYIZIAYb4QgENBB8WHU9w
ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSec3EaCPVAovnz
u01SwyEoc9Kt6zAfBgNVHSMEGDAWgBRF1wL+I61d2uBQ1467prsu2SYRGTANBgkq
hkiG9w0BAQsFAAOCAgEAPks4fHoAvzjidw8aJB+nX1pDzbWEbeWOl4xvYizvCN/c
rWeFp6+BnaUuQK5lXTS1z9m2bf70sSFOFTl6JHbpYdU7xr5Qfn69gfdIqeC2k52g
R29oYYRQSjMxufHW9IMufJ/FL1PW6EIlahx01WWla/wg6EC3Bygvnz5oCsDaNTwO
eWKSFVwnE1l6kOoxSparvOdrKpbqvmhUGy8qCRwvLtF2CRQihYSHnnU18oe78REP
Hkyqfjr/GxHn8senKJcN9AQ4RjxMeH/X1wr7Z+0OTpQh61AMEzzyO9sHy9uvxQoN
FREhTs53T10Br5Ppx7hp9S6jmiYgL8wtJwJIWFowq87VfuyeqEKhFXqjybeAXIlv
o4dpUd3woW5rBWhmo6tVs04vNtD6LFktbgkRIV8PPeb1M4QkJ8eD6z7tJNEHVGmK
S0vlDrdTzERwJlhh52d7a6vPXGG1/S7Mji/xyyDuWClaoJXy5NVr8DnKb1WudAXH
nspSoh4YApK4oWTKxYWuhs7rshxFu5A2T03RzJbgsAA/9wrZ4BZz4OCtEVUYoIhV
Qv4f2eOKB8d//vYJWon4R6ukYDZZnYNGplmxl47rzcEam1K88IeaBLN1hirvb9G9
Xk+wDNgZwJmHtYeJSOZHjiQCl2YJCiVn4gbuDxjrEJvye4s6n8fdn4sv2kX06MU=
-----END CERTIFICATE-----">>.