Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

byte serialization does not match go and Java versions. #164

Open
ieugen opened this issue Mar 23, 2024 · 2 comments
Open

byte serialization does not match go and Java versions. #164

ieugen opened this issue Mar 23, 2024 · 2 comments

Comments

@ieugen
Copy link

ieugen commented Mar 23, 2024

Hello,

While trying to implement nebula-certs in Clojure I encountered a bug with byte serialization.
Protojure reads the data ok but during byte serialization produces "wrong" byte arrays - different from what go and Java.
Hence my code to verify the signature in Clojure fails to work.

Discussion on Slack is here: https://clojurians.slack.com/archives/CNZQPJLD9/p1711152208441789 .

  (def a (file->bytes "ieugen.bytes"))
  (.formatHex hex a)

"0a0669657567656e12098180805080feffff0f2880d9f7af0630b8a5f7be063a200fba4efd592f08b540d0b396994fdfd7f0f123c2ed36fc5e717ff67d9952ae714a20037e9d6aa053411cd9c0c7ee315760b01b0384ff43f7144c4a4a77701e5df134"

  (def arr (protojure/->pb (:Details ieugen-crt)))
  (.formatHex hex arr)

"10818080501080feffff0f2880d9f7af064a20037e9d6aa053411cd9c0c7ee315760b01b0384ff43f7144c4a4a77701e5df13430b8a5f7be060a0669657567656e3a200fba4efd592f08b540d0b396994fdfd7f0f123c2ed36fc5e717ff67d9952ae71"


;; original bytes -> protojure map -> bytes
(.formatHex hex (protojure/->pb (cert/pb->RawNebulaCertificateDetails a)))

"10818080501080feffff0f2880d9f7af064a20037e9d6aa053411cd9c0c7ee315760b01b0384ff43f7144c4a4a77701e5df13430b8a5f7be060a0669657567656e3a200fba4efd592f08b540d0b396994fdfd7f0f123c2ed36fc5e717ff67d9952ae71"
(ns user
  (:require [clojure.java.io :as io]
            [protojure.protobuf :as protojure])
  (:import (java.time Instant)
           (org.bouncycastle.util.io.pem PemObject PemReader)
           (org.bouncycastle.crypto.signers Ed25519Signer)
           (org.bouncycastle.crypto.params AsymmetricKeyParameter
                                           Ed25519PublicKeyParameters)
           (java.util HexFormat)
           (nebula.cert Cert
                        Cert$RawNebulaCertificate
                        Cert$RawNebulaCertificateDetails)))

(defn read-pem
  "Read pem from file, url, etc.
   To pass String, wrap in InputStream."
  (^PemObject [pem]
   (let [pr (PemReader. (io/reader pem))]
     (.readPemObject pr))))


(def rnc (Cert$RawNebulaCertificate/parseFrom (.getContent (read-pem "ieugen.crt"))))

(->> rnc
      (.getDetails)
      (.toByteArray)
      (.formatHex hex))

Cert.java.txt
cert.proto.txt
ieugen.crt.txt
ieugen.bytes.txt
ieugen-crt.bytes.txt

@ieugen
Copy link
Author

ieugen commented Mar 23, 2024

I got a reply on Slack:

Greg Haskins
10 hours ago
If you were interested in taking a stab at what I think the problem is, I suspect its here:

;; FIXME: Add support for optimizing packable types

complex.cljc
;; FIXME: Add support for optimizing packable types

@ieugen
Copy link
Author

ieugen commented Mar 26, 2024

To go around this and still use protojure (clojure maps are nicer to work with) I do round-trip serialization.

I manage my code using protojure and when I need to serialize I do :

protojure -> bytes -> java protocol buffers -> bytes.

e.g.

(defn cert-details->bytes
  "Convert protojure a RawNebulaCertificateDetails map to bytes.
  Uses double serializations since protojure has a serialization bug with
  https://github.com/protojure/lib/issues/164
  Once it's fixed we can use only protojure."
  [details]
  (let [d-bytes ^bytes (protojure/->pb details)
        cert2 (Cert$RawNebulaCertificateDetails/parseFrom d-bytes)
        d-bytes2 (.toByteArray cert2)]
    d-bytes2))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant