Plaster

common-lisp
(defun %crc-event (raw-body) (ironclad:byte-array-to-hex-string (ironclad:digest-sequence :crc32 raw-body))) (defun %get-rsa-public-key (cert-url) (cl-tls:x509-decode (cdar (cl-tls::parse-pem (babel:octets-to-string (dex:get cert-url :use-connection-pool nil)))))) (defmethod %rsa-details ((key CL-TLS::X509V3-CERTIFICATE)) (with-slots (cl-tls::tbs-certificate) key (with-slots (cl-tls::subject-pki) cl-tls::tbs-certificate (getf cl-tls::subject-pki :subject-public-key)))) (defun %rsa-details->ironclad-rsa (list) (destructuring-bind (&key public-exponent modulus) list (make-instance 'ironclad:rsa-public-key :e public-exponent :n modulus))) (defun cert->public-key (cert-url) (%rsa-details->ironclad-rsa (%rsa-details (%get-rsa-public-key cert-url)))) (defun %hash-message (message) (ironclad:digest-sequence :sha256 message)) (defun %generate-signature-bytes (transmission-id timestamp webhook-id crc) (let ((to-sign (format nil "~A|~A|~A|~D" transmission-id timestamp webhook-id crc))) (babel:string-to-octets to-sign))) (defun %verify-message (public-key signature message) (cl-tls:rsassa-pkcs1.5-verify public-key message (cl-base64:base64-string-to-usb8-array signature) :sha256)) (defun verify-webhook (cert-url transmission-signature transmission-id timestamp webhook-id raw-body) (let* ((crc (%crc-event raw-body)) (x (print crc)) (key ;;(%get-rsa-public-key cert-url)) (cert->public-key cert-url)) (message (%generate-signature-bytes transmission-id timestamp webhook-id crc)) (hashed (%hash-message message))) (%verify-message key transmission-signature hashed)))