Skip to content
Snippets Groups Projects
Commit 3a0bb1fd authored by Josh Brooks's avatar Josh Brooks
Browse files

Implement bindings for downloading and verifying signed partial NDF

parent c062a271
Branches
Tags
2 merge requests!117Release,!74Implement bindings for downloading and verifying signed partial NDF
......@@ -12,7 +12,8 @@ import (
"net/http"
)
// Returns a []byte containing the JSON data describing client errors.
// DownloadErrorDB returns a []byte containing the JSON data
// describing client errors.
// See https://git.xx.network/elixxir/client-error-database/
func DownloadErrorDB() ([]byte, error) {
// Build a request for the file
......@@ -32,7 +33,8 @@ func DownloadErrorDB() ([]byte, error) {
return content, nil
}
// Returns a []byte containing the JSON data describing registered dApps.
// DownloadDAppRegistrationDB returns a []byte containing
// the JSON data describing registered dApps.
// See https://git.xx.network/elixxir/registered-dapps
func DownloadDAppRegistrationDB() ([]byte, error) {
// Build a request for the file
......
///////////////////////////////////////////////////////////////////////////////
// Copyright © 2021 xx network SEZC //
// //
// Use of this source code is governed by a license that can be found in the //
// LICENSE file //
///////////////////////////////////////////////////////////////////////////////
package bindings
import (
"encoding/base64"
"github.com/pkg/errors"
pb "gitlab.com/elixxir/comms/mixmessages"
"gitlab.com/xx_network/comms/signature"
"gitlab.com/xx_network/crypto/tls"
"google.golang.org/protobuf/proto"
"io/ioutil"
"net/http"
)
// todo: populate with actual URL
// ndfUrl is a hardcoded url to a bucket containing the signed NDF message.
const ndfUrl = `elixxir.io`
// DownloadSignedNdf retrieves the NDF from a hardcoded bucket URL.
// The NDF returned requires further processing and verification
// before being used. Use VerifySignedNdf to properly process
// the downloaded data returned.
// DO NOT USE THE RETURNED DATA TO START A CLIENT.
func DownloadSignedNdf() ([]byte, error) {
// Build a request for the file
resp, err := http.Get(ndfUrl)
if err != nil {
return nil, errors.WithMessagef(err, "Failed to retrieve " +
"NDF from %s", ndfUrl)
}
defer resp.Body.Close()
// Download contents of the file
signedNdfEncoded, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, errors.WithMessage(err, "Failed to read signed " +
"NDF response request")
}
return signedNdfEncoded, nil
}
// DownloadSignedNdfWithUrl retrieves the NDF from a specified URL.
// The NDF returned requires further processing and verification
// before being used. Use VerifySignedNdf to properly process
// the downloaded data returned.
// DO NOT USE THE RETURNED DATA TO START A CLIENT.
func DownloadSignedNdfWithUrl(url, cert string) ([]byte, error) {
// Build a reqeust for the file
resp, err := http.Get(url)
if err != nil {
return nil, errors.WithMessagef(err, "Failed to retrieve " +
"NDF from %s", url)
}
defer resp.Body.Close()
// Download contents of the file
signedNdfEncoded, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, errors.WithMessage(err, "Failed to read signed " +
"NDF response request")
}
return signedNdfEncoded, nil
}
// VerifySignedNdf takes the downloaded NDF from either
// DownloadSignedNdf or DownloadSignedNdfWithUrl (signedNdfEncoded)
// an the scheduling certificate (cert). The downloaded NDF is parsed
// into a protobuf containing a signature. The signature is verified using the
// passed in cert. Upon successful parsing and verification, the NDF is
// returned. This may be used to start a client.
func VerifySignedNdf(signedNdfEncoded []byte, cert string) ([]byte, error) {
// Base64 decode the signed NDF
signedNdfMarshaled, err := base64.StdEncoding.DecodeString(
string(signedNdfEncoded))
if err != nil {
return nil, errors.WithMessage(err, "Failed to decode signed NDF")
}
// Unmarshal the signed NDF
signedNdfMsg := &pb.NDF{}
err = proto.Unmarshal(signedNdfMarshaled, signedNdfMsg)
if err != nil {
return nil, errors.WithMessage(err, "Failed to unmarshal " +
"signed NDF into protobuf")
}
// Load the certificate from it's PEM contents
schedulingCert, err := tls.LoadCertificate(cert)
if err != nil {
return nil, errors.WithMessagef(err, "Failed to parse scheduling cert (%s)", cert)
}
// Extract the public key from the cert
schedulingPubKey, err := tls.ExtractPublicKey(schedulingCert)
if err != nil {
return nil, errors.WithMessage(err, "Failed to extract public key from cert")
}
// Verify signed NDF message
err = signature.VerifyRsa(signedNdfMsg, schedulingPubKey)
if err != nil {
return nil, errors.WithMessage(err, "Failed to verify signed NDF message")
}
return signedNdfMsg.Ndf, nil
}
///////////////////////////////////////////////////////////////////////////////
// Copyright © 2021 xx network SEZC //
// //
// Use of this source code is governed by a license that can be found in the //
// LICENSE file //
///////////////////////////////////////////////////////////////////////////////
package bindings
import "testing"
func TestDownloadSignedNdf(t *testing.T) {
// Todo: test once a proper URL is hardcoded
//content, err := DownloadSignedNdf()
//if err != nil {
// t.Errorf("Failed to download signed NDF: %v")
//}
//fmt.Printf("content: %s\n", string(content))
}
func TestDownloadSignedNdfWithUrl(t *testing.T) {
// todo: write test once a proper URL can be passed in
//content, err := DownloadSignedNdfWithUrl(exampleURL)
//if err != nil {
// t.Errorf("Failed to download signed NDF: %v")
//}
//fmt.Printf("content: %s\n", string(content))
}
// Tests
func TestVerifySignedNdf(t *testing.T) {
// todo write test once example data is collected
//ndf, err := VerifySignedNdf(testSignedNdf, testCert)
//if err != nil {
//
//}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment