anchor.diff:      (cond
         ;; RSA 
         ((and (= (length oid) 7)
  -	    (equal (butlast oid) '(1 2 840 113549 1 1)))
  +            (equal (butlast oid) '(1 2 840 113549 1 1)))
          (values :rsa
  -	       (case (seventh oid)
  -		 (2 :md2)
  -		 (4 :md5)
  -		 (5 :sha1)
  -		 (11 :sha256)
  -		 (12 :sha384)
  -		 (13 :sha512)
  -		 (otherwise
  -		  (error 'x509-decoding-error :text "Unknown digest algorithm")))))
  +               (case (seventh oid)
  +                 (2 :md2)
  +                 (4 :md5)
  +                 (5 :sha1)
  +                 (11 :sha256)
  +                 (12 :sha384)
  +                 (13 :sha512)
  +                 (otherwise
  +                  (error 'x509-decoding-error :text "Unknown digest algorithm")))))
         ;; DSA with sha1
         ((equal oid '(1 2 840 10040 4 3))
          (values :dsa :sha1))
  
positive.code:       ;; RSAPublicKey ::= SEQUENCE { modulus INTEGER, -- n publicExponent INTEGER -- e }
        (:rsa
         (let ((rsa-public-key (multiple-value-list
  			      (parse-der ov :start 1))))
  	 (unless (eql (first rsa-public-key) :sequence)
  	   (error 'x509-decoding-error :text "The subjectPublicKeyInfo bit string should contain an ASN.1 sequence"))
  	 (setf rsa-public-key (second rsa-public-key))
  	 (loop for element in rsa-public-key do
  	   (unless (eql (first element) :integer)
  	     (error 'x509-decoding-error :text "Expected integers in PKI field.")))
  	 (setf (getf pub-key :modulus) (second (first rsa-public-key)))
  	 (setf (getf pub-key :public-exponent) (second (second rsa-public-key)))))
        ;; DSA
        (:dsa
         (let ((dsa-public-key (multiple-value-list
  			      (parse-der ov :start 1))))
  	 (unless (eql (first dsa-public-key) :integer)
  	   (error 'x509-decoding-error :text "Expected a DSA public key; DSAPublicKey ::= INTEGER -- public key, Y"))
  	 (setf (getf pub-key :dsa-public-key) (second dsa-public-key))))
        ;; DH
        (:dh
         (let ((dh-public-value (multiple-value-list
  			       (parse-der ov :start 1))))
  	 (unless (eql (first dh-public-value) :integer)
  	   (error 'x509-decoding-error :text "Invalid encoding of subjectPublicKeyInfo"))
  	 (setf (getf pub-key :dh-Y) (second dh-public-value)))))
      pub-key))
  
  (defun parse-signature-algorithm (sig)
  
negative.code:   (case (length time-string)
      (13;;UTCTime := YYMMDDHHMMSSZ
       (encode-universal-time (parse-integer (subseq time-string 10 12))
                              (parse-integer (subseq time-string 8 10))
                              (parse-integer (subseq time-string 6 8))
                              (parse-integer (subseq time-string 4 6))
                              (parse-integer (subseq time-string 2 4))
                              (parse-integer (subseq time-string 0 2))))
      (15;;GeneralizedTime := YYYYMMDDHHMMSSZ
       (encode-universal-time (parse-integer (subseq time-string 12 14))
                              (parse-integer (subseq time-string 10 12))
                              (parse-integer (subseq time-string 8 10))
                              (parse-integer (subseq time-string 6 8))
                              (parse-integer (subseq time-string 4 6))
                              (parse-integer (subseq time-string 0 4))))))
  
  (defun get-raw-tbs (cert)
    "Get the raw octets of the DER-encoded tbsCertificate structure"
    (with-slots (raw) cert
      (let* ((certificate (asn-sequence-to-indices raw))
             (tbs-certificate (first certificate))
             (contents-start (second tbs-certificate))
             (contents-end (third tbs-certificate))
             (length (- contents-end contents-start)))
        (if (<= length 127)
            (subseq raw (- contents-start 2) contents-end)
            (subseq raw (- contents-start 2 (bytes-in-int length)) contents-end)))))
  
  (defun verify-signature (subject issuer)
    (with-slots ((subject-tbs-certificate tbs-certificate)
                 (subject-signature signature)
                 (subject-signature-algorithm signature-algorithm)) subject
      (with-slots ((issuer-tbs-certificate tbs-certificate)) issuer
        (let* ((signature-algorithm-id subject-signature-algorithm)
               (signature-algorithm (car signature-algorithm-id))
               (digest-algorithm (cdr signature-algorithm-id))
               (verification-digest (ironclad:digest-sequence
                                     digest-algorithm
                                     (get-raw-tbs subject)))
               (signature (subseq subject-signature 1))
               (issuer-pk (getf (subject-pki issuer-tbs-certificate)
                                :subject-public-key)))
          (case signature-algorithm
            (:rsa
             (let ((pub-key (ironclad:make-public-key :rsa
                                                      :n (getf issuer-pk :modulus)
                                                      :e (getf issuer-pk :public-exponent))))
               (setf signature (rsa-encrypt signature pub-key))
               (unless (= (aref signature 1) 1)
                 (return-from verify-signature nil))
               (setf signature (subseq signature (1+ (position 0 signature :start 1))))
               (multiple-value-bind (asn-type digest-info) (parse-der signature)
                 (unless (and (eql asn-type :sequence)
                              (= (length digest-info) 2))
                   (return-from verify-signature nil))
                 (destructuring-bind (digest-algorithm digest) digest-info
                   (declare (ignorable digest-algorithm))
                   (unless (eql (first digest) :octet-string) (return-from verify-signature nil))
                   (setf digest (second digest))
                   (timing-independent-compare verification-digest digest)))))
            (:dsa
             (let ((pub-key
                     (ironclad:make-public-key :dsa
                                               :p (getf issuer-pk :dsa-p)
                                               :q (getf issuer-pk :dsa-q)
                                               :g (getf issuer-pk :dsa-g)
                                               :y (getf issuer-pk :dsa-public-key))))
               (multiple-value-bind (asn-type dss-sig-value) (parse-der signature)
                 (unless (and (eql asn-type :sequence)
                              (= (length dss-sig-value) 2))
                   (return-from verify-signature nil))
                 (unless (every (lambda (arg) (asn-type-matches-p :integer arg)) dss-sig-value))
                 (destructuring-bind (r s) dss-sig-value
                   (setf signature (ironclad:make-signature :dsa :r (second r) :s (second s)))
                   (ironclad:verify-signature pub-key verification-digest signature))))))))))
  
  (defun time-valid-p (cert)
    (let* ((validity (validity (tbs-certificate cert)))
           (not-before (getf validity :not-before))
           (not-after (getf validity :not-after))
           (current-time
             (handler-case
                 (get-universal-time)
               (error ()
                 (error 'exception
                        :log "Could not determine system time for certificate validation"
                        :alert :internal-error)))))
      (<= not-before current-time not-after)))
  