scheme-libraries/retropikzel/tls/certificate.scm

60 lines
2.3 KiB
Scheme

;; 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)))