cl-rw

Layered streams for Common Lisp
git clone https://logand.com/git/cl-rw.git/
Log | Files | Refs

commit dd8ce8d50c2042bf76dc54e4c66529c27c1c47e6
parent b6e4b6fc6594ab42430accb7c253a2bba18e6da2
Author: Tomas Hlavaty <tom@logand.com>
Date:   Sat, 30 Aug 2014 16:23:58 +0200

read pem files added

Diffstat:
Mbase64.lisp | 45+++++++++++++++++++++++++--------------------
Mder.lisp | 43+++++++++++++++++++++++++++++++++++++++++++
Mrw.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)))))