// Return the XLRegMsg_Token corresponding to this cluster member. func TokenFromMemberInfo(mi *xcl.MemberInfo) ( token *XLRegMsg_Token, err error) { var ckBytes, skBytes []byte ck := mi.Peer.GetCommsPublicKey() ckBytes, err = xc.RSAPubKeyToWire(ck) if err == nil { skBytes, err = xc.RSAPubKeyToWire(mi.Peer.GetSigPublicKey()) if err == nil { name := mi.Peer.GetName() var myEnds []string for i := 0; i < mi.Peer.SizeConnectors(); i++ { myEnds = append(myEnds, mi.Peer.GetConnector(i).String()) } token = &XLRegMsg_Token{ Name: &name, Attrs: &mi.Attrs, ID: mi.Peer.GetNodeID().Value(), CommsKey: ckBytes, SigKey: skBytes, MyEnds: myEnds, } } } return }
// msgN, token including DigSig; gets Ack or Error func (upc *UpaxClient) IntroAndAck() (err error) { var ( name string id, ckBytes, skBytes, salt []byte digSig []byte // over name, id, ckBytes, skBytes, salt, in order ) // Send INTRO MSG ===================================== name = upc.GetName() id = upc.GetNodeID().Value() ckBytes, err = xc.RSAPubKeyToWire(&upc.ckPriv.PublicKey) if err == nil { skBytes, err = xc.RSAPubKeyToWire(&upc.skPriv.PublicKey) if err == nil { rng := xr.NewSystemRNG(0) n := uint64(rng.Int63()) salt = make([]byte, 8) binary.LittleEndian.PutUint64(salt, n) } } if err == nil { d := sha1.New() d.Write([]byte(name)) d.Write(id) d.Write(ckBytes) d.Write(skBytes) d.Write(salt) hash := d.Sum(nil) digSig, err = rsa.SignPKCS1v15( rand.Reader, upc.skPriv, crypto.SHA1, hash) } if err == nil { token := UpaxClientMsg_Token{ Name: &name, ID: id, CommsKey: ckBytes, SigKey: skBytes, Salt: salt, DigSig: digSig, } op := UpaxClientMsg_Intro request := &UpaxClientMsg{ Op: &op, ClientInfo: &token, } // SHOULD CHECK FOR TIMEOUT err = upc.writeMsg(request) } // Process ACK ======================================== if err == nil { var response *UpaxClientMsg // SHOULD CHECK FOR TIMEOUT AND VERIFY THAT IT'S AN ACK response, err = upc.readMsg() op := response.GetOp() if op != UpaxClientMsg_Ack { err = ExpectedAck } } return }
// Return the XLRegMsg_Token corresponding to this cluster client. func (mi *ClientInfo) Token() (token *XLRegMsg_Token, err error) { var ckBytes, skBytes []byte ck := mi.GetCommsPublicKey() // DEBUG if ck == nil { fmt.Printf("ClientInfo.Token: %s commsPubKey is nil\n", mi.GetName()) } // END ckBytes, err = xc.RSAPubKeyToWire(ck) if err == nil { skBytes, err = xc.RSAPubKeyToWire(mi.GetSigPublicKey()) if err == nil { name := mi.GetName() token = &XLRegMsg_Token{ Name: &name, Attrs: &mi.Attrs, ID: mi.GetNodeID().Value(), CommsKey: ckBytes, SigKey: skBytes, MyEnds: mi.MyEnds, } } } return }
func MakeHelloMsg(n *xn.Node) (m *XLatticeMsg, err error) { var ck, sk, salt, sig []byte cmd := XLatticeMsg_Hello id := n.GetNodeID().Value() ck, err = xc.RSAPubKeyToWire(n.GetCommsPublicKey()) if err == nil { sk, err = xc.RSAPubKeyToWire(n.GetSigPublicKey()) } if err == nil { sysRNG := xr.MakeSystemRNG() salt = make([]byte, 8) sysRNG.NextBytes(salt) chunks := [][]byte{id, ck, sk, salt} sig, err = n.Sign(chunks) } if err == nil { m = &XLatticeMsg{ Op: &cmd, MsgN: &ONE, ID: id, CommsKey: ck, SigKey: sk, Salt: salt, Sig: sig, } } return }
func (s *XLSuite) TestEncoding(c *C) { if VERBOSITY > 0 { fmt.Println("TEST_ENCODING") } const K = 2 nodes, accs := xn.MockLocalHostCluster(K) // lazy way to get keys defer func() { for i := 0; i < K; i++ { if accs[i] != nil { accs[i].Close() } } }() peer := nodes[0].GetPeer(0) pID := peer.GetNodeID().Value() pck, err := xc.RSAPubKeyToWire(peer.GetCommsPublicKey()) c.Assert(err, IsNil) psk, err := xc.RSAPubKeyToWire(peer.GetSigPublicKey()) c.Assert(err, IsNil) cmd := XLatticeMsg_Hello one := uint64(1) msg := &XLatticeMsg{ Op: &cmd, MsgN: &one, ID: pID, CommsKey: pck, SigKey: psk, } wired, err := EncodePacket(msg) c.Assert(err, IsNil) c.Assert(wired, Not(IsNil)) backAgain, err := DecodePacket(wired) c.Assert(err, IsNil) c.Assert(backAgain, Not(IsNil)) rewired, err := EncodePacket(msg) c.Assert(err, IsNil) c.Assert(rewired, Not(IsNil)) c.Assert(len(wired), Equals, len(rewired)) for i := 0; i < len(wired); i++ { c.Assert(wired[i], Equals, rewired[i]) } // DEBUG //fmt.Printf(" len ck %d bytes\n", len(msg.GetCommsKey())) // 294 //fmt.Printf(" len sk %d bytes\n", len(msg.GetSigKey())) // 294 //fmt.Println(" end TestEncoding") // END }
func (s *XLSuite) TestMakeHelloMsg(c *C) { if VERBOSITY > 0 { fmt.Println("TEST_MAKE_HELLO_MSG") } rng := xr.MakeSimpleRNG() id := make([]byte, xu.SHA1_BIN_LEN) rng.NextBytes(id) nodeID, err := xi.NewNodeID(id) c.Assert(err, IsNil) name := rng.NextFileName(8) lfs := "tmp/" + hex.EncodeToString(id) mrX, err := xn.NewNew(name, nodeID, lfs) c.Assert(err, IsNil) cPubKey := mrX.GetCommsPublicKey() c.Assert(cPubKey, Not(IsNil)) sPubKey := mrX.GetSigPublicKey() c.Assert(sPubKey, Not(IsNil)) // convert MrX's keys to wire form as byte slices wcPubKey, err := xc.RSAPubKeyToWire(cPubKey) c.Assert(err, IsNil) c.Assert(len(wcPubKey) > 0, Equals, true) wsPubKey, err := xc.RSAPubKeyToWire(sPubKey) c.Assert(err, IsNil) c.Assert(len(wsPubKey) > 0, Equals, true) c.Assert(wsPubKey, Not(IsNil)) hello, err := MakeHelloMsg(mrX) c.Assert(err, IsNil) c.Assert(hello, Not(IsNil)) // check NodeID idInMsg := hello.GetID() // a byte slice, not a NodeID c.Assert(id, DeepEquals, idInMsg) // these are byte slices mcPubKey := hello.GetCommsKey() msPubKey := hello.GetSigKey() c.Assert(len(mcPubKey), Equals, len(wcPubKey)) c.Assert(len(msPubKey), Equals, len(wsPubKey)) // FAILS 0, 294 c.Assert(wcPubKey, DeepEquals, mcPubKey) c.Assert(wsPubKey, DeepEquals, msPubKey) }
func (sl SignedBList) GetHash() []byte { d := sha1.New() // public key in PKCS1 format pk, _ := xc.RSAPubKeyToWire(sl.PubKey) d.Write(pk) d.Write([]byte(sl.Title)) return d.Sum(nil) }
// If dl.sk is not nil, return an error if it does not match the // public part of private key. // // If there are any items in the DigiList, sign it. If this succeeds, // any existing signature is overwritten and the public part of the key // is written to the data structure, to dl.sk. // func (dl *DigiList) Sign(skPriv *rsa.PrivateKey, subClass DigiListI) ( err error) { var ( hash []byte n uint sk *rsa.PublicKey skWire []byte ) if skPriv == nil { err = NilRSAPrivKey } else if subClass == nil { err = NilSubClass } else { n = subClass.Size() // DEBUG // fmt.Printf("DigiList.Sign(): subclass has %d chunks\n", n) // END sk = &skPriv.PublicKey // DEVIATION FROM SPEC - we ignore any existing dl.sk skWire, err = xc.RSAPubKeyToWire(sk) } if err == nil { d := sha1.New() d.Write(skWire) // public key to hash d.Write([]byte(dl.title)) // title b := make([]byte, 8) binary.LittleEndian.PutUint64(b, uint64(dl.timestamp)) d.Write(b) // timestamp to hash for i := uint(0); i < n; i++ { var itemHash []byte itemHash, err = subClass.HashItem(i) if err != nil { break } d.Write(itemHash) } if err == nil { hash = d.Sum(nil) } } if err == nil { dl.sk = sk dl.digSig, err = rsa.SignPKCS1v15( rand.Reader, skPriv, crypto.SHA1, hash) } return }
// Calculates and returns the document hash. func (sl *SignedBList) calcDocHash() []byte { d := sha1.New() d.Write([]byte(sl.Title)) // serialized time d.Write([]byte(sl.Timestamp.String())) // serialized public key, ignoring possible error pk, _ := xc.RSAPubKeyToWire(sl.PubKey) d.Write(pk) // content lines count := uint(len(sl.Content)) for n := uint(0); n < count; n++ { // XXX any errors are being ignored line, _ := sl.Get(n) d.Write([]byte(line)) } return d.Sum(nil) }
// If the DigiList has been signed, verify the digital signature, // returning an error if it does not validate. func (dl *DigiList) Verify(subClass DigiListI) (err error) { var ( hash []byte n uint skWire []byte ) if subClass == nil { err = NilSubClass } else if dl.digSig == nil { err = NoDigSig } else { n = subClass.Size() skWire, err = xc.RSAPubKeyToWire(dl.sk) } if err == nil { d := sha1.New() d.Write(skWire) // public key to hash d.Write([]byte(dl.title)) // title b := make([]byte, 8) binary.LittleEndian.PutUint64(b, uint64(dl.timestamp)) d.Write(b) // timestamp to hash for i := uint(0); i < n; i++ { var itemHash []byte itemHash, err = subClass.HashItem(i) if err != nil { break } d.Write(itemHash) } if err == nil { hash = d.Sum(nil) } } if err == nil { err = rsa.VerifyPKCS1v15(dl.sk, crypto.SHA1, hash, dl.digSig) } return }
func (mm *MemberMaker) MemberAndOK() (err error) { var ( ckBytes, skBytes []byte digSig []byte hash []byte id []byte myEnds []string ) // XXX attrs not actually dealt with node := mm.ClusterMember.Node nodeID := node.GetNodeID() if nodeID != nil { id = nodeID.Value() } name := node.GetName() ckPriv := node.GetCommsPrivateKey() skPriv := node.GetSigPrivateKey() // Send MEMBER MSG ========================================== // DEBUF fmt.Println("MemberMaker: have node info") // END aBytes := make([]byte, 8) binary.LittleEndian.PutUint64(aBytes, mm.ProposedAttrs) ckBytes, err = xc.RSAPubKeyToWire(&ckPriv.PublicKey) if err == nil { skBytes, err = xc.RSAPubKeyToWire(&skPriv.PublicKey) if err == nil { for i := 0; i < node.SizeEndPoints(); i++ { myEnd := node.GetEndPoint(i).String() if strings.HasPrefix(myEnd, "TcpEndPoint: ") { myEnd = myEnd[13:] } myEnds = append(myEnds, myEnd) } // calculate hash over fields in canonical order d := sha1.New() d.Write([]byte(name)) d.Write(aBytes) d.Write(ckBytes) d.Write(skBytes) for i := 0; i < len(myEnds); i++ { d.Write([]byte(myEnds[i])) } hash = d.Sum(nil) // calculate digital signature digSig, err = rsa.SignPKCS1v15(rand.Reader, skPriv, crypto.SHA1, hash) // DEBUF //fmt.Printf(" MM: digSig added; error = %v\n", err) // END } } if err == nil { token := &XLRegMsg_Token{ Name: &name, ID: id, Attrs: &mm.ProposedAttrs, CommsKey: ckBytes, SigKey: skBytes, MyEnds: myEnds, DigSig: digSig, } op := XLRegMsg_Member request := &XLRegMsg{ Op: &op, // MemberName: &name, // XXX redundant DROPPED MemberSpecs: token, } // SHOULD CHECK FOR TIMEOUT err = mm.writeMsg(request) // DEBUF //fmt.Printf(" MM: Member msg written; error = %v\n", err) // END } // Process CLIENT_OK -------------------------------------------- // SHOULD CHECK FOR TIMEOUT response, err := mm.readMsg() if err == nil { // XXX Could check registry's notion of MemberID: //id := response.GetMemberID() //var nodeID *xi.NodeID //nodeID, err = xi.New(id) mm.Attrs = response.GetMemberAttrs() } // DEBUF //fmt.Printf(" MM: response received; error = %v\n", err) // END return }
func (h *InHandler) handleHello(n *xn.Node) (err error) { var ( m *XLatticeMsg msgN uint64 id, ck, sk, sig, salt []byte peer *xn.Peer ) m, err = h.readMsg() // message must be a Hello if err == nil { if m.GetOp() != XLatticeMsg_Hello { err = MissingHello } } if err == nil { // the message is a hello; is its NodeID that of a known peer? id = m.GetID() if id == nil { // DEBUG fmt.Printf("handleHello: message has no ID field\n") // END err = NilPeer } else { peer, err = n.FindPeer(id) if err == nil { if peer == nil { err = xn.NotAKnownPeer } else { h.Peer = peer } } } } // On any error up to here silently close the connection and delete // the handler. if err != nil { h.Cnx.Close() h = nil return } // message is a hello from a known peer ------------------------- // MsgN must be 1 msgN = m.GetMsgN() h.MsgN = msgN ck = m.GetCommsKey() // comms key as byte slice sk = m.GetSigKey() // sig key as byte slice salt = m.GetSalt() sig = m.GetSig() // digital signature var serCK, serSK []byte if h.MsgN != 1 { err = ExpectedMsgOne } if err == nil { peerID := peer.GetNodeID().Value() if !bytes.Equal(id, peerID) { fmt.Println("NOT SAME NODE ID") // XXX should log err = NotExpectedNodeID } } if err == nil { serCK, err = xc.RSAPubKeyToWire(peer.GetCommsPublicKey()) if err == nil { if !bytes.Equal(serCK, ck) { fmt.Println("NOT SAME COMMS KEY") // XXX should log err = NotExpectedCommsKey } } } if err == nil { serSK, err = xc.RSAPubKeyToWire(peer.GetSigPublicKey()) if err == nil { if !bytes.Equal(serSK, sk) { fmt.Println("NOT SAME SIG KEY") // XXX should log err = NotExpectedSigKey } } } if err == nil { sigPubKey := peer.GetSigPublicKey() d := sha1.New() d.Write(id) d.Write(ck) d.Write(sk) d.Write(salt) hash := d.Sum(nil) err = rsa.VerifyPKCS1v15(sigPubKey, cr.SHA1, hash, sig) } if err == nil { // Everything is good; so Ack, leaving cnx open. h.Peer.MarkUp() // we consider the peer live h.Peer.LastContact() err = h.simpleAck(msgN) } else { // Send the text of the error to the peer; the send itself // may of course cause an error, but we will ignore that. // The peer is NOT marked as up. h.errorReply(err) } return }