diff --git a/.cirrus.yml b/.cirrus.yml index 40ab771..8bd0eb2 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -13,6 +13,8 @@ task: - source testdata/move_to_gopath.bash fetch_script: - go get -tags "$GOX_TAGS" -d -v -t github.com/$CIRRUS_REPO_FULL_NAME/... + - go generate github.com/namecoin/x509-compressed/... + - go get -tags "$GOX_TAGS" -d -v -t github.com/$CIRRUS_REPO_FULL_NAME/... lint_script: - cd $(go env GOPATH)/src/github.com/$CIRRUS_REPO_FULL_NAME/ - golangci-lint run --no-config --enable-all --disable gochecknoglobals,gomnd $GOLANGCI_ARGS -v --timeout 5m --out-format json > $CIRRUS_WORKING_DIR/lint-report.json @@ -59,6 +61,8 @@ task: - source testdata/move_to_gopath.bash fetch_script: - go get -tags "$GOX_TAGS" -d -v -t github.com/$CIRRUS_REPO_FULL_NAME/... + - go generate github.com/namecoin/x509-compressed/... + - go get -tags "$GOX_TAGS" -d -v -t github.com/$CIRRUS_REPO_FULL_NAME/... test_script: go test -tags "$GOX_TAGS" -v github.com/$CIRRUS_REPO_FULL_NAME/... env: GOX_TAGS: "" @@ -85,6 +89,8 @@ task: fetch_script: - go get -tags "$GOX_TAGS" -d -v -t github.com/$CIRRUS_REPO_FULL_NAME/... - GOOS=windows GOARCH=amd64 go get -tags "$GOX_TAGS" -d -v -t github.com/$CIRRUS_REPO_FULL_NAME/... + - go generate github.com/namecoin/x509-compressed/... + - go get -tags "$GOX_TAGS" -d -v -t github.com/$CIRRUS_REPO_FULL_NAME/... build_script: - rm -rf idist - CGO_ENABLED=1 gox -tags="$GOX_TAGS" -parallel=8 -osarch 'linux/386 linux/amd64 linux/arm linux/arm64 linux/ppc64le' -output "$GOPATH/releasing/idist/$CIRRUS_REPO_NAME-$CIRRUS_TAG-{{.OS}}_{{.Arch}}/bin/{{.Dir}}" github.com/$CIRRUS_REPO_FULL_NAME/... diff --git a/README.md b/README.md index 35161a9..360688c 100644 --- a/README.md +++ b/README.md @@ -96,9 +96,13 @@ Option A: Using Go build commands (works on any platform): familar with Go, setting it to the path to an empty directory will suffice. The directory will be filled with build files.) -2. Run `go get -t -u github.com/namecoin/ncdns/...`. The ncdns source code will be - retrieved automatically, and ncdns will be built. The binaries will be at - $GOPATH/bin/ncdns.. +2. Run `go get -d -t -u github.com/namecoin/ncdns/...`. The ncdns source code will be + retrieved automatically. + +3. Run `go generate github.com/namecoin/x509_compressed/...`. The compressed public key patch will be applied. + +4. Run `go get -t -u github.com/namecoin/ncdns/...`. ncdns will be built. The binaries will be at + $GOPATH/bin/ncdns. Option B: Using Makefile (non-Windows platforms): diff --git a/ncdomain/convert_tls.go b/ncdomain/convert_tls.go index 3cd9fb9..c48dc49 100644 --- a/ncdomain/convert_tls.go +++ b/ncdomain/convert_tls.go @@ -13,6 +13,7 @@ import ( "github.com/namecoin/ncdns/certdehydrate" "github.com/namecoin/ncdns/util" + x509_compressed "github.com/namecoin/x509-compressed/x509" ) type Value struct { @@ -77,34 +78,34 @@ func parseTLSADehydrated(tlsa1dehydrated interface{}, v *Value) error { func parseTLSADANE(tlsa1dane interface{}, v *Value) error { if tlsa, ok := tlsa1dane.([]interface{}); ok { - // Format: ["443", "tcp", 1, 2, 3, "base64 certificate data"] + // Format: [1, 2, 3, "base64 certificate data"] if len(tlsa) < 4 { - return fmt.Errorf("TLSA item must have six items") + return fmt.Errorf("TLSA item must have four items") } a1, ok := tlsa[0].(float64) if !ok { - return fmt.Errorf("Third item in TLSA value must be an integer (usage)") + return fmt.Errorf("First item in TLSA value must be an integer (usage)") } a2, ok := tlsa[1].(float64) if !ok { - return fmt.Errorf("Fourth item in TLSA value must be an integer (selector)") + return fmt.Errorf("Second item in TLSA value must be an integer (selector)") } a3, ok := tlsa[2].(float64) if !ok { - return fmt.Errorf("Fifth item in TLSA value must be an integer (match type)") + return fmt.Errorf("Third item in TLSA value must be an integer (match type)") } a4, ok := tlsa[3].(string) if !ok { - return fmt.Errorf("Sixth item in TLSA value must be a string (certificate)") + return fmt.Errorf("Fourth item in TLSA value must be a string (certificate)") } a4b, err := base64.StdEncoding.DecodeString(a4) if err != nil { - return fmt.Errorf("Fourth item in DS value must be valid base64: %v", err) + return fmt.Errorf("Fourth item in TLSA value must be valid base64: %v", err) } a4h := hex.EncodeToString(a4b) @@ -118,6 +119,36 @@ func parseTLSADANE(tlsa1dane interface{}, v *Value) error { Certificate: strings.ToUpper(a4h), }) + // Handle compressed public keys specially + // Check if this TLSA is a public key preimage + if uint8(a2) == 1 && uint8(a3) == 0 { + pubDecompressed, err := x509_compressed.ParsePKIXPublicKey(a4b) + if err != nil { + return nil + } + + pubDecompressedBytes, err := x509.MarshalPKIXPublicKey(pubDecompressed) + if err != nil { + return nil + } + + pubDecompressedHex := hex.EncodeToString(pubDecompressedBytes) + + if pubDecompressedHex == a4h { + // The pubkey wasn't compressed, so decompressing had no impact. + return nil + } + + v.TLSA = append(v.TLSA, &dns.TLSA{ + Hdr: dns.RR_Header{Name: "", Rrtype: dns.TypeTLSA, Class: dns.ClassINET, + Ttl: defaultTTL}, + Usage: uint8(a1), + Selector: uint8(a2), + MatchingType: uint8(a3), + Certificate: strings.ToUpper(pubDecompressedHex), + }) + } + return nil } else { return fmt.Errorf("TLSA item must be an array")