Skip to content

Commit

Permalink
fix algs
Browse files Browse the repository at this point in the history
  • Loading branch information
5HT committed Aug 2, 2023
1 parent a401ab3 commit afc6f1f
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 77 deletions.
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ config :ca,
tsp_port: 1001,
ca_port: 8088,
logger_level: :info,
logger: [{:handler, :default, :logger_std_h,
logger: [{:handler, :default2, :logger_std_h,
%{level: :info,
id: :synrc,
max_size: 2000,
Expand Down
1 change: 0 additions & 1 deletion lib/alg.ex
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ defmodule CA.ALG do
{:'dhSinglePass-stdDH-hkdf-sha256-scheme', {1,2,840,113549,1,9,16,3,19}},
{:'dhSinglePass-stdDH-hkdf-sha384-scheme', {1,2,840,113549,1,9,16,3,20}},
{:'dhSinglePass-stdDH-hkdf-sha512-scheme', {1,2,840,113549,1,9,16,3,21}},
{:defaultPBKDF2, {1,3,6,1,5,5,8,1,2}},
{:'hMAC-SHA1', {1,3,6,1,5,5,8,1,2}},
{:'id-sha1', {1,3,14,3,2,26}},
{:sect163k1, {1,3,132,0,1}},
Expand Down
2 changes: 1 addition & 1 deletion lib/ca.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ defmodule CA do

def init([]), do: {:ok, { {:one_for_one, 5, 10}, []} }
def start(_type, _args) do
:logger.add_handlers(:ldap)
:logger.add_handlers(:ca)
CA.CMP.start
CA.CMC.start
CA.TSP.start
Expand Down
104 changes: 57 additions & 47 deletions lib/cmp.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,64 @@ defmodule CA.CMP do
accept(socket)
end

def baseKey(pass, salt, iter), do:
def loop(socket) do
case :gen_tcp.recv(socket, 0) do
{:ok, data} ->
[_headers,body] = :string.split data, "\r\n\r\n", :all
{:ok,dec} = :'PKIXCMP-2009'.decode(:'PKIMessage', body)
{:PKIMessage, header, body, code, _extra} = dec
__MODULE__.message(socket, header, body, code)
loop(socket)
{:error, :closed} -> :exit
end
end

def baseKey(pass, salt, iter, owf \\ :sha256), do:
:lists.foldl(fn _, acc ->
:crypto.hash(:sha256, acc) end, pass <> salt,
:crypto.hash(owf, acc) end, pass <> salt,
:lists.seq(1,iter))

def protection(:asn1_NOVALUE), do: {"","","","",1}
def protection(protectionAlg) do
{_,oid,{_,param}} = protectionAlg
{:ok, parameters} = :"PKIXCMP-2009".decode(:'PBMParameter', param)
{:PBMParameter, salt, {_,owf,_}, counter, {_,mac,_} } = parameters
{oid, salt, owf, mac, counter}
end

def validateProtection(header, body, code) do
{:PKIHeader, _, _, _, _, protectionAlg, _, _, _, _, _, _, _} = header
{_oid, salt, _owf, _mac, counter} = protection(protectionAlg)
incomingProtection = CA."ProtectedPart"(header: header, body: body)
{:ok, bin} = :"PKIXCMP-2009".encode(:'ProtectedPart', incomingProtection)
verifyKey = baseKey(:application.get_env(:ca, :pbm, "0000"), salt, counter)
:crypto.mac(:hmac, CA.KDF.hs(:erlang.size(code)), verifyKey, bin)
{oid, salt, owfoid, _mac, counter} = protection(protectionAlg)
case CA.ALG.lookup(oid) do
{:'id-PasswordBasedMac', _ } ->
incomingProtection = CA."ProtectedPart"(header: header, body: body)
{:ok, bin} = :"PKIXCMP-2009".encode(:'ProtectedPart', incomingProtection)
{owf,_} = CA.ALG.lookup(owfoid) # SHA-2
pbm = :application.get_env(:ca, :pbm, "0000") # DH shared secret
verifyKey = baseKey(pbm, salt, counter, owf)
mac = CA.KDF.hs(:erlang.size(code))
case CA.ALG.lookup(macoid) do

Check warning on line 55 in lib/cmp.ex

View workflow job for this annotation

GitHub Actions / build

variable "macoid" does not exist and is being expanded to "macoid()", please use parentheses to remove the ambiguity or change the variable name

Check failure on line 55 in lib/cmp.ex

View workflow job for this annotation

GitHub Actions / build

** (CompileError) lib/cmp.ex:55: undefined function macoid/0
{:'hMAC-SHA1',_} -> :crypto.mac(:hmac, mac, verifyKey, bin)
_ -> :crypto.mac(:hmac, mac, verifyKey, bin)
end
{_, _ } ->
""
end
end

def answer(socket, header, body, code) do
message = CA."PKIMessage"(header: header, body: body, protection: code)
{:ok, bytes} = :'PKIXCMP-2009'.encode(:'PKIMessage', message)
res = "HTTP/1.0 200 OK\r\n"
<> "Server: SYNRC CA/CMP\r\n"
<> "Content-Type: application/pkixcmp\r\n\r\n"
<> :erlang.iolist_to_binary(bytes)
:gen_tcp.send(socket, res)
end

def message(_socket, _header, {:ir, req}, _) do
:lists.map(fn {:CertReqMsg, req, sig, code} ->
:io.format 'request: ~p~n', [req]
:io.format 'signature: ~p~n', [sig]
:io.format 'code: ~p~n', [code]
:logger.info 'request: ~p ~p ~p~n', [req,sig,code]
end, req)
end

Expand All @@ -43,19 +82,17 @@ defmodule CA.CMP do
end

def message(socket, header, {:p10cr, csr} = body, code) do
{:PKIHeader, pvno, from, to, messageTime, protectionAlg, _senderKID, _recipKID,
{:PKIHeader, pvno, from, to, messageTime, protectionAlg, senderKID, _recipKID,
transactionID, senderNonce, _recipNonce, _freeText, _generalInfo} = header
code = validateProtection(header, body, code)
true = code == validateProtection(header, body, code)
:logger.info 'P10CR ~p~n', [senderKID]

{ca_key, ca} = CA.CSR.read_ca()
subject = X509.CSR.subject(csr)
:io.format '~p~n',[subject]
true = X509.CSR.valid?(CA.parseSubj(csr))
cert = X509.Certificate.new(X509.CSR.public_key(csr), CA.CAdES.subj(subject), ca, ca_key,
extensions: [subject_alt_name: X509.Certificate.Extension.subject_alt_name(["synrc.com"]) ])

:file.write_file "m2-1.pem", X509.Certificate.to_pem(cert)

reply = CA."CertRepMessage"(response:
[ CA."CertResponse"(certReqId: 0,
certifiedKeyPair: CA."CertifiedKeyPair"(certOrEncCert:
Expand All @@ -65,7 +102,8 @@ defmodule CA.CMP do
pkibody = {:cp, reply}
pkiheader = CA."PKIHeader"(sender: to, recipient: from, pvno: pvno, recipNonce: senderNonce,
transactionID: transactionID, protectionAlg: protectionAlg, messageTime: messageTime)
answer(socket, pkiheader, pkibody, validateProtection(pkiheader, pkibody, code))
:ok = answer(socket, pkiheader, pkibody, validateProtection(pkiheader, pkibody, code))
:logger.info 'CP ~p~n', [senderNonce]
end

def message(socket, header, {:certConf, statuses}, code) do
Expand All @@ -77,41 +115,13 @@ defmodule CA.CMP do

pkibody = {:pkiconf, :asn1_NOVALUE}
pkiheader = CA."PKIHeader"(header, sender: to, recipient: from, recipNonce: senderNonce)
answer(socket, pkiheader, pkibody, validateProtection(pkiheader, pkibody, code))
:ok = answer(socket, pkiheader, pkibody, validateProtection(pkiheader, pkibody, code))
:logger.info 'PKICONF ~p~n', [senderNonce]

end

def message(_socket, _header, body, _code) do
:logger.info 'Strange PKIMessage request ~p', [body]
end

def protection(:asn1_NOVALUE), do: {"","","","",1}
def protection(protectionAlg) do
{_,oid,{_,param}} = protectionAlg
{:ok, parameters} = :"PKIXCMP-2009".decode(:'PBMParameter', param)
{:PBMParameter, salt, {_,owf,_}, counter, {_,mac,_} } = parameters
{oid, salt, owf, mac, counter}
end

def answer(socket, header, body, code) do
message = CA."PKIMessage"(header: header, body: body, protection: code)
{:ok, bytes} = :'PKIXCMP-2009'.encode(:'PKIMessage', message)
res = "HTTP/1.0 200 OK\r\n"
<> "Server: SYNRC CA/CMP\r\n"
<> "Content-Type: application/pkixcmp\r\n\r\n"
<> :erlang.iolist_to_binary(bytes)
:gen_tcp.send(socket, res)
end

def loop(socket) do
case :gen_tcp.recv(socket, 0) do
{:ok, data} ->
{{_,_headers},asn} = :asn1rt_nif.decode_ber_tlv(data)
[_,body] = :string.split asn, "\r\n\r\n", :all
{:ok,dec} = :'PKIXCMP-2009'.decode(:'PKIMessage', body)
{:PKIMessage, header, body, code, _extra} = dec
__MODULE__.message(socket, header, body, code)
loop(socket)
{:error, :closed} -> :exit
end
end
end
30 changes: 15 additions & 15 deletions lib/csr.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ defmodule CA.CSR do

def ca() do
ca_key = X509.PrivateKey.new_ec(:secp384r1)
ca = X509.Certificate.self_signed(ca_key,
"/C=UA/L=Kyiv/O=SYNRC/CN=CSR-CMP", template: :root_ca)
dn = "/C=UA/L=Київ/O=SYNRC/CN=CA"
:logger.info 'CSR CMP DN ~p~n', [dn]
ca = X509.Certificate.self_signed(ca_key, dn, template: :root_ca)
der = :public_key.der_encode(:ECPrivateKey, ca_key)
pem = :public_key.pem_encode([{:ECPrivateKey, der, :not_encrypted}])
:file.write_file "ca.key", pem
Expand All @@ -22,11 +23,12 @@ defmodule CA.CSR do

def server(name) do
{ca_key, ca} = read_ca()
dn = "/C=UA/L=Київ/O=SYNRC/CN=" <> name
server_key = X509.PrivateKey.new_ec(:secp384r1)
X509.Certificate.new(X509.PublicKey.derive(server_key),
"/C=UA/L=Kyiv/O=SYNRC/CN=" <> name, ca, ca_key,
extensions: [subject_alt_name:
X509.Certificate.Extension.subject_alt_name(["n2o.dev", "erp.uno"]) ])
:logger.info 'CSR SERVER DN ~p~n', [dn]
X509.Certificate.new(X509.PublicKey.derive(server_key),
dn, ca, ca_key, extensions: [subject_alt_name:
X509.Certificate.Extension.subject_alt_name(["synrc.com"]) ])
end

def csr(user) do
Expand All @@ -35,18 +37,16 @@ defmodule CA.CSR do
der = :public_key.der_encode(:ECPrivateKey, priv)
pem = :public_key.pem_encode([{:ECPrivateKey, der, :not_encrypted}])
:file.write_file(user <> ".key", pem)
:io.format '~p~n', [priv]
csr = X509.CSR.new(priv, "/C=UA/L=Kyiv/O=SYNRC/CN=" <> user,
extension_request: [X509.Certificate.Extension.subject_alt_name(["n2o.dev"])])
:io.format 'CSR: ~p~n', [csr]
dn = "/C=UA/L=Київ/O=SYNRC/CN=" <> user
:logger.info 'CSR USER DN ~p~n', [dn]
csr = X509.CSR.new(priv, dn, extension_request: [
X509.Certificate.Extension.subject_alt_name(["synrc.com"])])
:file.write_file(user <> ".csr", X509.CSR.to_pem(csr))
true = X509.CSR.valid?(csr)
subject = X509.CSR.subject(csr)
:io.format 'Subject ~p~n', [subject]
:io.format 'CSR ~p~n', [csr]
X509.Certificate.new(X509.CSR.public_key(csr), subject, ca, ca_key,
extensions: [subject_alt_name:
X509.Certificate.Extension.subject_alt_name(["n2o.dev", "erp.uno"]) ])
X509.Certificate.new(X509.CSR.public_key(csr),
subject, ca, ca_key, extensions: [subject_alt_name:
X509.Certificate.Extension.subject_alt_name(["synrc.com"]) ])
csr
end

Expand Down
32 changes: 22 additions & 10 deletions lib/ecdsa.ex
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
defmodule CA.ECDSA do

@moduledoc "CA/ECDSA ECC Signature."
require CA

# openssl dgst -sha256 -sign $client.key mix.exs > mix.sig
# openssl dgst -sha256 -verify $client.pub -signature mix.sig mix.exs
# CA.ECDSA.verify "mix.exs", "mix.sig", "#{client}.pub"

def verify(file, signature, pem) do
{:ok, msg} = :file.read_file file
{:ok, sig} = :file.read_file signature
verifyBin(msg, sig, public(pem))
def signBin(msg, priv) do
CA."ECPrivateKey"(privateKey: point, parameters: {:namedCurve, oid}) = priv
:crypto.sign(:ecdsa, :sha256, msg,
[point, :crypto.ec_curve(:pubkey_cert_records.namedCurves(oid))])
end

def verifyBin(msg, sig, public) do
{CA."ECPoint"(point: point), {_namedCurve, oid}} = public
def verifyBin(msg, sig, pub) do
{CA."ECPoint"(point: point), {_namedCurve, oid}} = pub
:crypto.verify(:ecdsa, :sha256, msg, sig,
[point, :crypto.ec_curve(:pubkey_cert_records.namedCurves(oid))])
[point, :crypto.ec_curve(:pubkey_cert_records.namedCurves(oid))])
end

def public(name) do
:public_key.pem_entry_decode(hd(:public_key.pem_decode(
:erlang.element(2, :file.read_file( name )))))
def sign(file, priv) do
{:ok, msg} = :file.read_file file
{:ok, key} = :file.read_file priv
signBin(msg, private(key))
end

def verify(file, signature, pub) do
{:ok, msg} = :file.read_file file
{:ok, sig} = :file.read_file signature
{:ok, pem} = :file.read_file pub
verifyBin(msg, sig, public(pem))
end

def private(bin), do: :erlang.element(2,X509.PrivateKey.from_pem(bin))
def public(bin), do: :public_key.pem_entry_decode(hd(:public_key.pem_decode(bin)))

end
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule CA.Mixfile do
def project() do
[
app: :ca,
version: "4.7.27",
version: "4.8.2",
elixir: "~> 1.7",
description: "CA CXC 138 21 Certificate Authority",
package: package(),
Expand Down
2 changes: 1 addition & 1 deletion src/ca.app.src
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{application, ca,
[
{description, "CA CXC 138 21 Certificate Authority"},
{vsn, "4.7.26"},
{vsn, "4.8.2"},
{registered, []},
{applications, [kernel,stdlib,ranch,cowboy]},
{mod, { 'Elixir.CA', []}},
Expand Down

0 comments on commit afc6f1f

Please sign in to comment.