func (sk *RsaPrivateKey) Bytes() ([]byte, error) { b := x509.MarshalPKCS1PrivateKey(sk.k) pbmes := new(PBPrivateKey) typ := KeyType_RSA pbmes.Type = &typ pbmes.Data = b return proto.Marshal(pbmes) }
func newTestMessage() *pb.MyMessage { msg := &pb.MyMessage{ Count: proto.Int32(42), Name: proto.String("Dave"), Quote: proto.String(`"I didn't want to go."`), Pet: []string{"bunny", "kitty", "horsey"}, Inner: &pb.InnerMessage{ Host: proto.String("footrest.syd"), Port: proto.Int32(7001), Connected: proto.Bool(true), }, Others: []*pb.OtherMessage{ { Key: proto.Int64(0xdeadbeef), Value: []byte{1, 65, 7, 12}, }, { Weight: proto.Float32(6.022), Inner: &pb.InnerMessage{ Host: proto.String("lesha.mtv"), Port: proto.Int32(8002), }, }, }, Bikeshed: pb.MyMessage_BLUE.Enum(), Somegroup: &pb.MyMessage_SomeGroup{ GroupField: proto.Int32(8), }, // One normally wouldn't do this. // This is an undeclared tag 13, as a varint (wire type 0) with value 4. XXX_unrecognized: []byte{13<<3 | 0, 4}, } ext := &pb.Ext{ Data: proto.String("Big gobs for big rats"), } if err := proto.SetExtension(msg, pb.E_Ext_More, ext); err != nil { panic(err) } greetings := []string{"adg", "easy", "cow"} if err := proto.SetExtension(msg, pb.E_Greeting, greetings); err != nil { panic(err) } // Add an unknown extension. We marshal a pb.Ext, and fake the ID. b, err := proto.Marshal(&pb.Ext{Data: proto.String("3G skiing")}) if err != nil { panic(err) } b = append(proto.EncodeVarint(201<<3|proto.WireBytes), b...) proto.SetRawExtension(msg, 201, b) // Extensions can be plain fields, too, so let's test that. b = append(proto.EncodeVarint(202<<3|proto.WireVarint), 19) proto.SetRawExtension(msg, 202, b) return msg }
func Wrap(data []byte, typ PBWrapper_MessageType) ([]byte, error) { wrapper := new(PBWrapper) wrapper.Message = data wrapper.Type = &typ b, err := proto.Marshal(wrapper) if err != nil { return nil, err } return b, nil }
// Cleaner looking helper function to make a new message struct func NewMessage(p *peer.Peer, data proto.Message) *Message { bytes, err := proto.Marshal(data) if err != nil { u.PErr("%v\n", err.Error()) return nil } return &Message{ Peer: p, Data: bytes, } }
func FolderPBData() []byte { pbfile := new(PBData) typ := PBData_Directory pbfile.Type = &typ data, err := proto.Marshal(pbfile) if err != nil { //this really shouldnt happen, i promise panic(err) } return data }
func (pk *RsaPublicKey) Bytes() ([]byte, error) { b, err := x509.MarshalPKIXPublicKey(pk.k) if err != nil { return nil, err } pbmes := new(PBPublicKey) typ := KeyType_RSA pbmes.Type = &typ pbmes.Data = b return proto.Marshal(pbmes) }
func FilePBData(data []byte) []byte { pbfile := new(PBData) typ := PBData_File pbfile.Type = &typ pbfile.Data = data data, err := proto.Marshal(pbfile) if err != nil { //this really shouldnt happen, i promise panic(err) } return data }
func WrapData(b []byte) []byte { pbdata := new(PBData) typ := PBData_Raw pbdata.Data = b pbdata.Type = &typ out, err := proto.Marshal(pbdata) if err != nil { // This shouldnt happen. seriously. panic(err) } return out }
// Performs initial communication with this peer to share node ID's and // initiate communication. (secureIn, secureOut, error) func Handshake(self, remote *peer.Peer, in <-chan []byte, out chan<- []byte) (<-chan []byte, chan<- []byte, error) { // Generate and send Hello packet. // Hello = (rand, PublicKey, Supported) nonce := make([]byte, 16) _, err := rand.Read(nonce) if err != nil { return nil, nil, err } hello := new(Hello) myPubKey, err := self.PubKey.Bytes() if err != nil { return nil, nil, err } hello.Rand = nonce hello.Pubkey = myPubKey hello.Exchanges = &SupportedExchanges hello.Ciphers = &SupportedCiphers hello.Hashes = &SupportedHashes encoded, err := proto.Marshal(hello) if err != nil { return nil, nil, err } out <- encoded // Parse their Hello packet and generate an Exchange packet. // Exchange = (EphemeralPubKey, Signature) resp := <-in helloResp := new(Hello) err = proto.Unmarshal(resp, helloResp) if err != nil { return nil, nil, err } remote.PubKey, err = ci.UnmarshalPublicKey(helloResp.GetPubkey()) if err != nil { return nil, nil, err } remote.ID, err = IDFromPubKey(remote.PubKey) if err != nil { return nil, nil, err } exchange, err := selectBest(SupportedExchanges, helloResp.GetExchanges()) if err != nil { return nil, nil, err } cipherType, err := selectBest(SupportedCiphers, helloResp.GetCiphers()) if err != nil { return nil, nil, err } hashType, err := selectBest(SupportedHashes, helloResp.GetHashes()) if err != nil { return nil, nil, err } epubkey, done, err := ci.GenerateEKeyPair(exchange) // Generate EphemeralPubKey if err != nil { return nil, nil, err } var handshake bytes.Buffer // Gather corpus to sign. handshake.Write(encoded) handshake.Write(resp) handshake.Write(epubkey) exPacket := new(Exchange) exPacket.Epubkey = epubkey exPacket.Signature, err = self.PrivKey.Sign(handshake.Bytes()) if err != nil { return nil, nil, err } exEncoded, err := proto.Marshal(exPacket) if err != nil { return nil, nil, err } out <- exEncoded // Parse their Exchange packet and generate a Finish packet. // Finish = E('Finish') resp1 := <-in exchangeResp := new(Exchange) err = proto.Unmarshal(resp1, exchangeResp) if err != nil { return nil, nil, err } var theirHandshake bytes.Buffer _, err = theirHandshake.Write(resp) if err != nil { return nil, nil, err } _, err = theirHandshake.Write(encoded) if err != nil { return nil, nil, err } _, err = theirHandshake.Write(exchangeResp.GetEpubkey()) if err != nil { return nil, nil, err } ok, err := remote.PubKey.Verify(theirHandshake.Bytes(), exchangeResp.GetSignature()) if err != nil { return nil, nil, err } if !ok { return nil, nil, errors.New("Bad signature!") } secret, err := done(exchangeResp.GetEpubkey()) if err != nil { return nil, nil, err } cmp := bytes.Compare(myPubKey, helloResp.GetPubkey()) mIV, tIV, mCKey, tCKey, mMKey, tMKey := ci.KeyStretcher(cmp, cipherType, hashType, secret) secureIn := make(chan []byte) secureOut := make(chan []byte) go secureInProxy(in, secureIn, hashType, tIV, tCKey, tMKey) go secureOutProxy(out, secureOut, hashType, mIV, mCKey, mMKey) finished := []byte("Finished") secureOut <- finished resp2 := <-secureIn if bytes.Compare(resp2, finished) != 0 { return nil, nil, errors.New("Negotiation failed.") } u.DOut("[%s] identify: Got node id: %s\n", self.ID.Pretty(), remote.ID.Pretty()) return secureIn, secureOut, nil }