diff --git a/lib/curves/ecdsa.ex b/lib/curves/ecdsa.ex index 3d7ad68..2f3bfe6 100644 --- a/lib/curves/ecdsa.ex +++ b/lib/curves/ecdsa.ex @@ -4,12 +4,6 @@ defmodule CA.ECDSA do require CA.Jacobian require CA.ECDSA.OTP - def numberFromString(data) do - Base.encode16(data) - |> Integer.parse(16) - |> (fn {parsedInt, ""} -> parsedInt end).() - end - def sign(message, privateKey, options \\ []) do %{hashfunc: hashfunc} = Enum.into(options, %{hashfunc: :sha256}) number = :crypto.hash(hashfunc, message) |> numberFromString() @@ -26,16 +20,37 @@ defmodule CA.ECDSA do def public(bin), do: #:erlang.element(1,:erlang.element(2, :public_key.pem_entry_decode(hd(:public_key.pem_decode(bin))) - def verify(file, signature, pub) do + def numberFromString(string) do + Base.encode16(string) + |> Integer.parse(16) + |> (fn {parsedInt, ""} -> parsedInt end).() + end + + def decodeIntegerFromECPoint(ec) do + {{:ECPoint, bin2}, {:namedCurve, oid}} = ec + bin = :binary.part(bin2,1,:erlang.size(bin2)-1) + curve = CA.KnownCurves.getCurveByOid(oid) + baseLength = CA.Curve.getLength(curve) + xs = :binary.part(bin, 0, baseLength) + ys = :binary.part(bin, baseLength, :erlang.size(bin) - baseLength) + point = %CA.Point{ x: numberFromString(xs), y: numberFromString(ys)} + :io.format 'ECPoint.x: ~p~n', [xs] + :io.format 'ECPoint.y: ~p~n', [ys] + :io.format 'ECPoint: ~p~n', [point] + point + end + + def verify(file, signature_file, pub) do {:ok, msg} = :file.read_file file {:ok, pem} = :file.read_file pub - verify(msg, CA.ECDSA.OTP.signature(signature), public(pem), []) + verify(msg, CA.ECDSA.OTP.signature(signature_file), decodeIntegerFromECPoint(public(pem)), []) end def verify(message, {r,s}, publicKey, options) do + :io.format '{r,s}: ~p~n', [{r,s}] %{hashfunc: hashfunc} = Enum.into(options, %{hashfunc: :sha256}) number = :crypto.hash(hashfunc, message) |> numberFromString() - curve = CA.KnownCurves.secp256k1() + curve = CA.KnownCurves.secp384r1() inv = CA.Jacobian.inv(s, curve."N") v = CA.Jacobian.add( CA.Jacobian.multiply(curve."G", CA.Integer.modulo(number * inv, curve."N"), diff --git a/lib/curves/knownCurves.ex b/lib/curves/knownCurves.ex index 754c9cb..db5a9a3 100644 --- a/lib/curves/knownCurves.ex +++ b/lib/curves/knownCurves.ex @@ -2,14 +2,17 @@ defmodule CA.KnownCurves do require CA.Curve require CA.Point - @secp256k1Oid {1, 3, 132, 0, 10} - @secp256k1name :secp256k1 + @secp384r1 {1, 3, 132, 0, 34} + @secp256k1 {1, 3, 132, 0, 10} @prime256v1 {1, 2, 840, 10045, 3, 1, 7} + @secp384r1name :secp384r1 + @secp256k1name :secp256k1 @prime256v1name :prime256v1 def getCurveByOid(oid) do case oid do - @secp256k1Oid -> secp256k1() + @secp256k1 -> secp256k1() + @secp384r1 -> secp384r1() @prime256v1 -> prime256v1() end end @@ -17,6 +20,7 @@ defmodule CA.KnownCurves do def getCurveByName(name) do case name do @secp256k1name -> secp256k1() + @secp384r1name -> secp384r1() @prime256v1name -> prime256v1() end end @@ -32,7 +36,7 @@ defmodule CA.KnownCurves do x: 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, y: 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8 }, - oid: @secp256k1Oid + oid: @secp256k1 } end @@ -50,4 +54,19 @@ defmodule CA.KnownCurves do oid: @prime256v1 } end + + def secp384r1() do + %CA.Curve{ + name: @secp384r1name, + A: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc, + B: 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef, + P: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff, + N: 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973, + G: %CA.Point{ + x: 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7, + y: 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f + }, + oid: @secp384r1 + } + end end diff --git a/lib/ecdsa.ex b/lib/ecdsa.ex index 8d4be46..b825c97 100644 --- a/lib/ecdsa.ex +++ b/lib/ecdsa.ex @@ -16,6 +16,7 @@ defmodule CA.ECDSA.OTP do def verifyBin(msg, sig, pub) do {CA."ECPoint"(point: point), {:namedCurve, oid}} = pub + :io.format 'oid: ~p~n', [oid] :crypto.verify(:ecdsa, :sha256, msg, sig, [point, :crypto.ec_curve(:pubkey_cert_records.namedCurves(oid))]) end @@ -23,7 +24,10 @@ defmodule CA.ECDSA.OTP do def signature(name) do {:ok, sig} = :file.read_file name {{_,[{_,r},{_,s}]},""} = :asn1rt_nif.decode_ber_tlv sig - {r,s} + :io.format 'r: ~p~n', [r] + :io.format 's: ~p~n', [s] + { :ca_enroll.decode_integer(r), + :ca_enroll.decode_integer(s) } end def sign(file, priv) do diff --git a/src/ca_enroll.erl b/src/ca_enroll.erl index 629ab0f..bee4cb5 100644 --- a/src/ca_enroll.erl +++ b/src/ca_enroll.erl @@ -1,7 +1,12 @@ -module(ca_enroll). -copyright('Namdak Tonpa'). -include_lib("public_key/include/public_key.hrl"). --export([init/2, boot/0, boot/1, cwd/0, ca/1, enroll/3, service/3, maybe_service/3, echo/2]). +-export([init/2, boot/0, boot/1, cwd/0, ca/1, enroll/3, service/3, maybe_service/3, echo/2, decode_integer/1]). + +decode_integer(Bin) -> + Len = byte_size(Bin), + <> = Bin, + Int. init(Req,Opts) -> Method = cowboy_req:method(Req),