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
No related branches found
No related tags found
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