;; https://www.oss.com/asn1/resources/asn1-made-simple/introduction.html ;; https://www.oss.com/asn1/resources/asn1-made-simple/asn1-quick-reference/basic-encoding-rules.html ;; https://www.oss.com/asn1/resources/asn1-made-simple/asn1-quick-reference.html ;; https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/#length (define (read-sequence-length bytes start-index) (let ((bits (integer->list (bytevector-u8-ref bytes start-index)))) bits)) (define (read-asn.1-sequence bytes start-index result) (when (not (= (bytevector-u8-ref bytes start-index) 48)) (error "read-asn.1-sequence error: start index is not sequence tag (48)" bytes start-index)) (if (or (> start-index (bytevector-length bytes)) (not (= (bytevector-u8-ref bytes start-index) 48))) result (let ((sequence-length+length-bytes-length (bytevector-u8-ref bytes (+ start-index 1))) ) (read-asn.1-sequence-items bytes (+ start-index sequence-length) (append result (list (bytevector-copy bytes start-index (+ start-index (- sequence-length 1))))))))) (define (read-asn.1-integer bytes start-index) (when (not (= (bytevector-u8-ref bytes start-index) 2)) (error "read-asn.1-integer error: bytes start index is not integer type tag" bytes start-index)) (bytevector-uint-ref bytes (+ start-index 1 ;; ASN.1-type 1 ;; ASN.1-length ) 'big (bytevector-u8-ref bytes (+ start-index 1)) ;; ASN.1-length )) (define (bytes->certificate bytes) (let ((asn.1-sequence-length (bytevector-u8-ref bytes 1))) `(certificate (asn.1-sequence-tag . ,(bytevector-u8-ref bytes 0)) (asn.1-sequence-length . ,asn.1-sequence-length) (tbs-certificate . ,(read-asn.1-sequence bytes 0 '())) (bytes ,bytes) ;(version . ,(bytevector-u8-ref bytes 2)) ;(serial-number . , (read-asn.1-integer bytes 3)) ) )) (define (read-certificates bytes start-index) ;; https://datatracker.ietf.org/doc/html/rfc5280#section-4.1 (map bytes->certificate (read-asn.1-sequence bytes start-index)))