Beispiel #1
0
// 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
}
Beispiel #2
0
// 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
}
Beispiel #3
0
// 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
}
Beispiel #4
0
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
}
Beispiel #5
0
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
}
Beispiel #6
0
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)
}
Beispiel #7
0
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)
}
Beispiel #8
0
// 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
}
Beispiel #9
0
// 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)
}
Beispiel #10
0
// 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
}
Beispiel #11
0
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
}
Beispiel #12
0
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
}