commit dd8ce8d50c2042bf76dc54e4c66529c27c1c47e6
parent b6e4b6fc6594ab42430accb7c253a2bba18e6da2
Author: Tomas Hlavaty <tom@logand.com>
Date: Sat, 30 Aug 2014 16:23:58 +0200
read pem files added
Diffstat:
M | base64.lisp | | | 45 | +++++++++++++++++++++++++-------------------- |
M | der.lisp | | | 43 | +++++++++++++++++++++++++++++++++++++++++++ |
M | rw.lisp | | | 7 | +++++++ |
3 files changed, 75 insertions(+), 20 deletions(-)
diff --git a/base64.lisp b/base64.lisp
@@ -27,7 +27,7 @@
(in-package :rw.base64)
-(defun encode-reader (reader &optional table wrap) ;; TODO wrap 76
+(defun encode-reader (reader &key table wrap) ;; TODO wrap 76
(let (pending
(table (or table
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")))
@@ -39,7 +39,8 @@
(flet ((%next ()
(let ((x (rw:next reader)))
(when x
- (logand #xff (if (characterp x) (char-code x) x)))))
+ (assert (<= 0 x #xff))
+ x)))
(%map (x n)
(char table (ldb (byte 6 n) x))))
(let* ((a (%next))
@@ -51,7 +52,7 @@
(push (%map x 12) pending)
(%map x 18))))))))
-(defun decode-reader (reader &optional table) ;; TODO skip newlines?
+(defun decode-reader (reader &key table) ;; TODO skip newlines?
(let (pending
(table (or table
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")))
@@ -60,21 +61,25 @@
(pending (pop pending))
((not (rw:peek reader)) nil)
(t
- (flet ((%next ()
- (let ((x (rw:next reader)))
- (unless (eql #\= x)
- (position x table))))
- (%map (x n)
- (code-char (ldb (byte 8 n) x))))
- (let* ((a (%next))
- (b (%next))
- (c (%next))
- (d (%next))
- (x (+ (ash a 18) (ash b 12) (ash (or c 0) 6) (or d 0))))
- (when d (push (%map x 0) pending))
- (when c (push (%map x 8) pending))
- (%map x 16))))))))
+ (rw:skip reader)
+ (let ((x (rw:peek reader)))
+ (when (and x (position x table))
+ (flet ((%next ()
+ (let ((x (rw:next reader)))
+ (unless (eql #\= x)
+ (position x table))))
+ (%map (x n)
+ (ldb (byte 8 n) x)))
+ (let* ((a (%next))
+ (b (%next))
+ (c (%next))
+ (d (%next))
+ (x (+ (ash a 18) (ash b 12) (ash (or c 0) 6) (or d 0))))
+ (when d (push (%map x 0) pending))
+ (when c (push (%map x 8) pending))
+ (%map x 16))))))))))
-;;(rw:till (rw:peek-reader (decode-reader (rw:peek-reader (encode-reader (rw:peek-reader (rw:reader "any carnal pleasure.")))))))
-;;(rw:till (rw:peek-reader (encode-reader (rw:peek-reader (rw:reader "any carnal pleasure.")))))
-;;(rw:till (rw:peek-reader (decode-reader (rw:peek-reader (rw:reader "YW55IGNhcm5hbCBwbGVhc3VyZS4=")))))
+;;(rw:till (rw:peek-reader (decode-reader (rw:peek-reader (encode-reader (rw:peek-reader (rw:reader #(1 2 3 4 32))))))))
+;;(rw:till (rw:peek-reader (encode-reader (rw:peek-reader (rw:wrap-reader (rw:reader "any carnal pleasure.") #'char-code)))))
+;;(rw:till (rw:peek-reader (rw:wrap-reader (decode-reader (rw:peek-reader (encode-reader (rw:peek-reader (rw:wrap-reader (rw:reader "any carnal pleasure.") #'char-code))))) #'code-char)))
+;;(rw:till (rw:peek-reader (rw:wrap-reader (decode-reader (rw:peek-reader (rw:reader "YW55IGNhcm5hbCBwbGVhc3VyZS4="))) #'code-char)))
diff --git a/der.lisp b/der.lisp
@@ -338,3 +338,46 @@
;;(decode (rw:reader '(6 6 #x2a #x86 #x48 #x86 #xf7 #x0d)))
;;(decode (rw:reader '(3 4 6 #x6e #x5d #xc0))) ; '(:bit-string "011011100101110111")
;;(encode w '(:bit-string "011011100101110111")) ;; '(3 4 6 #x6e #x5d #xc0)
+(defun read-pem-key (reader)
+ (let ((x (rw:till reader '(#\return #\newline))))
+ (rw:skip reader)
+ (cond
+ ;; -----BEGIN PRIVATE KEY-----
+ ((equal x
+ '(#\- #\- #\- #\- #\-
+ #\B #\E #\G #\I #\N #\space
+ #\P #\R #\I #\V #\A #\T #\E #\space
+ #\K #\E #\Y
+ #\- #\- #\- #\- #\-))
+ (prog1 (decode (rw.base64:decode-reader reader))
+ (rw:skip reader)
+ (assert
+ (equal '(#\- #\- #\- #\- #\-
+ #\E #\N #\D #\space
+ #\P #\R #\I #\V #\A #\T #\E #\space
+ #\K #\E #\Y
+ #\- #\- #\- #\- #\-)
+ (rw:till reader '(#\return #\newline))))))
+ ;; -----BEGIN CERTIFICATE-----
+ ((equal x
+ '(#\- #\- #\- #\- #\-
+ #\B #\E #\G #\I #\N #\space
+ #\C #\E #\R #\T #\I #\F #\I #\C #\A #\T #\E
+ #\- #\- #\- #\- #\-))
+ (prog1 (decode (rw.base64:decode-reader reader))
+ (rw:skip reader)
+ (assert
+ (equal '(#\- #\- #\- #\- #\-
+ #\E #\N #\D #\space
+ #\C #\E #\R #\T #\I #\F #\I #\C #\A #\T #\E
+ #\- #\- #\- #\- #\-)
+ (rw:till reader '(#\return #\newline))))))
+ (t
+ (error "unexpected pem delimiter ~{~a~}" x)))))
+
+(defun read-pem-file (pathname)
+ (with-open-file (s pathname)
+ (let ((r (rw:peek-reader (rw:char-reader s))))
+ (loop
+ while (progn (rw:skip r) (rw:peek r))
+ collect (read-pem-key r)))))
diff --git a/rw.lisp b/rw.lisp
@@ -45,6 +45,7 @@
:skip
:slurp
:till
+ :wrap-reader
:write-octets
:write-u16
:write-u32
@@ -342,3 +343,9 @@
(incf offset)
(funcall reader))))
reader))
+
+(defun wrap-reader (reader fn)
+ (lambda ()
+ (let ((z (rw:next reader)))
+ (when z
+ (funcall fn z)))))