Skip to content

Instantly share code, notes, and snippets.

@rlipscombe
Created November 17, 2022 17:40
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 rlipscombe/f64786a2caa0a992ea83c5c2e1a037b1 to your computer and use it in GitHub Desktop.
Save rlipscombe/f64786a2caa0a992ea83c5c2e1a037b1 to your computer and use it in GitHub Desktop.
Generate a certificate signing request in Erlang, EC key.
-module(x509).
-export([
create_private_key/0,
private_key_to_pem/1,
create_request/2,
request_to_pem/1
]).
-include_lib("public_key/include/public_key.hrl").
% PrivateKey = x509:create_private_key().
% file:write_file("server.key", x509:private_key_to_pem(PrivateKey)).
% CSR = x509:create_request(PrivateKey, "server").
% file:write_file("server.csr", x509:request_to_pem(CSR)).
%
% openssl req -in server.csr -text -noout
create_private_key() ->
CurveId = secp256r1,
{PubKey, PrivKey} = crypto:generate_key(ecdh, CurveId),
PrivateKey = #'ECPrivateKey'{
version = 1,
privateKey = PrivKey,
parameters = {namedCurve, pubkey_cert_records:namedCurves(CurveId)},
publicKey = PubKey
},
PrivateKey.
private_key_to_pem(PrivateKey = #'ECPrivateKey'{}) ->
public_key:pem_encode([public_key:pem_entry_encode('ECPrivateKey', PrivateKey)]).
create_request(PrivateKey = #'ECPrivateKey'{publicKey = PubKey, parameters = Params}, SubjectCN) ->
Hash = sha256,
SubjectRDN = pubkey_cert_records:transform(
{rdnSequence, [
[
#'AttributeTypeAndValue'{
type = ?'id-at-commonName', value = {utf8String, SubjectCN}
}
]
]},
encode
),
Attributes = [],
SubjectPKInfo = #'CertificationRequestInfo_subjectPKInfo'{
algorithm = #'CertificationRequestInfo_subjectPKInfo_algorithm'{
algorithm = ?'id-ecPublicKey',
parameters = {asn1_OPENTYPE, public_key:der_encode('EcpkParameters', Params)}
},
subjectPublicKey = PubKey
},
CertificationRequestInfo = #'CertificationRequestInfo'{
version = v1,
subject = SubjectRDN,
subjectPKInfo = SubjectPKInfo,
attributes = Attributes
},
SignatureAlgorithm = #'CertificationRequest_signatureAlgorithm'{
algorithm = ?'ecdsa-with-SHA256', parameters = asn1_NOVALUE
},
CertificationRequestInfoDer = public_key:der_encode(
'CertificationRequestInfo', CertificationRequestInfo
),
Signature =
public_key:sign(
CertificationRequestInfoDer,
Hash,
PrivateKey
),
#'CertificationRequest'{
certificationRequestInfo = CertificationRequestInfo,
signatureAlgorithm = SignatureAlgorithm,
signature = Signature
}.
request_to_pem(CSR = #'CertificationRequest'{}) ->
public_key:pem_encode([public_key:pem_entry_encode('CertificationRequest', CSR)]).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment