Open zapko opened 3 years ago
Thank you for your suggestion.
When I wrote this library, Ironclad, CL cryptography library, didn't have the support of ECDSA. But, it seems Ironclad finally got it? (https://github.com/sharplispers/ironclad/issues/33)
I can't start working on this because of my situation, so it'd be appreciated if you send me a PR. When you have some time, please look into this file: https://github.com/fukamachi/jose/blob/master/jws.lisp
Thank you for the hints! I'll check them out and see if I can find solution myself.
@zapko I'm also working on apple api at the moment xD. did you got something working yet? should I try (I'm new to lisp, so not sure if I succeed)?
As far as I see it, we can just use the rsa functions. But I'm at the moment unable to load a ec pem file.
I drafted out an implementation for a signing method https://github.com/fukamachi/jose/compare/master...zapko:es256 ,Ā but I'm having troubles testing it. It looks like asn1
and/or pem
packages require updates to support EC keys.
I think I read an :rsa somewhere in the code of pem
. Also my Quicklisp cannot find pem, unsure if my ql is broken.
You have to clone it into ql:local-projects folder from https://github.com/fukamachi/pem.Ā It's not in the global registry. Same for asn1
I've managed to run it,Ā but the signature it produces is not correct:
(jose:encode :es256
(ironclad:make-private-key :secp256r1
:x (cl-base64:base64-string-to-usb8-array
(cdar (pem/parser:parse-file *ecdsa-private-key*))
:uri nil))
'(("hello" . "world")))
Not sure what exactly I'm doing wrong.
; Signing method
(defun ecdsa-sign-message (digest-spec private-key message &key (start 0) (end (length message)))
(let ((digest (ironclad:digest-sequence digest-spec message :start start :end end)))
(ironclad:sign-message private-key digest :start 0 :end (length digest))))
Yay, I've managed to make it work!
The problem was that I wasn't reading file with the private key correctly.
With this addition to pem
package:
(defun read-private-ec-key (key)
(let* ((der (cl-base64:base64-string-to-usb8-array key))
(der-parsed (asn1:decode der))
(x (cdr (caddar der-parsed)))) ; There should be a way to make it better, but I don't know how
(ironclad:make-private-key :secp256r1 :x x)))
(defun read-from-file (pem)
(let ((data (pem/parser:parse-file pem)))
(let ((public-key (cdr (assoc "PUBLIC KEY" data :test #'string=)))
(private-key (cdr (assoc "RSA PRIVATE KEY" data :test #'string=)))
(private-ec-key (cdr (assoc "EC PRIVATE KEY" data :test #'string=))))
(cond
(public-key (read-public-key public-key))
(private-key (read-private-key private-key))
(private-ec-key (read-private-ec-key private-ec-key))))))
This produces verified signature:
(jose:encode :es256
(pem:read-from-file *ecdsa-private-key*) ; Path to key file
'(("hello" . "world")))
Thank you for this project and for other CL projects you have šš¼ Itās very inspiring to see amount of work that was done to support modern development in common lisp.
Iām trying to start a package that will provide development tools around Appleās AppstoreConnect API in Common Lisp and it requires JWT with ES256 encryption.
Is it possible to add it? Or maybe if you can provide a guidelines on what changes are required or were to start them I can try to do it myself, but Iām still learning the language and donāt feel very confident about this path.