diff --git a/client/cli.go b/client/cli.go index 4a195b4..213bd16 100644 --- a/client/cli.go +++ b/client/cli.go @@ -808,10 +808,11 @@ func (c *cliClient) showIdentity() { heading: "Identity", rows: []cliRow{ cliRow{cols: []string{"Server", terminalEscape(c.server, false)}}, - cliRow{cols: []string{"Public identity", fmt.Sprintf("%x", c.identityPublic[:])}}, + cliRow{cols: []string{"Fingerprint", fmt.Sprintf("%d", c.fingerprint())}}, cliRow{cols: []string{"Public key", fmt.Sprintf("%x", c.pub[:])}}, + cliRow{cols: []string{"Identity key", fmt.Sprintf("%x", c.identityPublic[:])}}, + cliRow{cols: []string{"Generation", fmt.Sprintf("%d", c.generation)}}, cliRow{cols: []string{"State file", terminalEscape(c.stateFilename, false)}}, - cliRow{cols: []string{"Group generation", fmt.Sprintf("%d", c.generation)}}, }, } table.WriteTo(c.term) @@ -1858,9 +1859,10 @@ func (c *cliClient) showContact(contact *Contact) { rows: []cliRow{ cliRow{cols: []string{"Name", terminalEscape(contact.name, false)}}, cliRow{cols: []string{"Server", terminalEscape(contact.theirServer, false)}}, - cliRow{cols: []string{"Generation", fmt.Sprintf("%d", contact.generation)}}, - cliRow{cols: []string{"Public key", fmt.Sprintf("%x", contact.theirPub[:])}}, + cliRow{cols: []string{"Fingerprint", fmt.Sprintf("%d", contact.fingerprint())}}, cliRow{cols: []string{"Identity key", fmt.Sprintf("%x", contact.theirIdentityPublic[:])}}, + cliRow{cols: []string{"Public key", fmt.Sprintf("%x", contact.theirPub[:])}}, + cliRow{cols: []string{"Generation", fmt.Sprintf("%d", contact.generation)}}, cliRow{cols: []string{"Client version", fmt.Sprintf("%d", contact.supportedVersion)}}, }, } diff --git a/client/client.go b/client/client.go index 0d5ddef..18d17a0 100644 --- a/client/client.go +++ b/client/client.go @@ -477,6 +477,17 @@ type Contact struct { cliId cliId } +func (contact *Contact) fingerprint() []byte { + if contact.isPending { + return []byte{} + } + return fingerprint(contact.theirPub[:]) +} + +func (c *client) fingerprint() []byte { + return fingerprint(c.pub[:]) +} + // Event represents a log entry. This does not apply to the global log, which // is quite chatty, but rather to significant events related to a given // contact. These events are surfaced in the UI and recorded in the statefile. @@ -802,11 +813,8 @@ func (c *client) loadUI() error { copy(c.priv[:], priv[:]) copy(c.pub[:], pub[:]) - if c.disableV2Ratchet { - c.randBytes(c.identity[:]) - } else { - extra25519.PrivateKeyToCurve25519(&c.identity, priv) - } + // Avoid tying identity to pub to keep pub from being a selector + c.randBytes(c.identity[:]) curve25519.ScalarBaseMult(&c.identityPublic, &c.identity) c.groupPriv, err = bbssig.GenerateGroup(rand.Reader) @@ -907,6 +915,17 @@ func (contact *Contact) indicator() Indicator { return indicatorNone } +func (contact *Contact) ratchetVersion(disableV2Ratchet bool) int32 { + if disableV2Ratchet || contact.supportedVersion < 1 { + return 1 + } + if protoVersion <= contact.supportedVersion { + return protoVersion + } else { + return contact.supportedVersion + } +} + func (contact *Contact) processKeyExchange(kxsBytes []byte, testing, simulateOldClient, disableV2Ratchet bool) error { var kxs pond.SignedKeyExchange if err := proto.Unmarshal(kxsBytes, &kxs); err != nil { @@ -951,6 +970,11 @@ func (contact *Contact) processKeyExchange(kxsBytes []byte, testing, simulateOld } copy(contact.theirIdentityPublic[:], kx.IdentityPublic) + // Contact might be using the v2 ratchet if kx.SupportedVersion exists + if kx.SupportedVersion != nil { + contact.supportedVersion = *kx.SupportedVersion + } + if simulateOldClient { kx.Dh1 = nil } @@ -966,12 +990,9 @@ func (contact *Contact) processKeyExchange(kxsBytes []byte, testing, simulateOld copy(contact.theirCurrentDHPublic[:], kx.Dh) contact.ratchet = nil } else { - // If the identity and ed25519 public keys are the same (modulo - // isomorphism) then the contact is using the v2 ratchet. - var ed25519Public, curve25519Public [32]byte - copy(ed25519Public[:], kx.PublicKey) - extra25519.PublicKeyToCurve25519(&curve25519Public, &ed25519Public) - v2 := !disableV2Ratchet && bytes.Equal(curve25519Public[:], kx.IdentityPublic[:]) + // Just leave contact.supportedVersion=0 if not specified, but maybe + // worth setting supportedVersion=1 if we've thought about it more. + v2 := (contact.ratchetVersion(disableV2Ratchet) == 2) if err := contact.ratchet.CompleteKeyExchange(&kx, v2); err != nil { return err } @@ -1035,11 +1056,20 @@ func (c *client) registerId(id uint64) { } func (c *client) newRatchet(contact *Contact) *ratchet.Ratchet { + // contact.ratchetVersion(disableV2Ratchet) == 2 r := ratchet.New(c.rand) - r.MyIdentityPrivate = &c.identity r.MySigningPublic = &c.pub - r.TheirIdentityPublic = &contact.theirIdentityPublic r.TheirSigningPublic = &contact.theirPub + switch contact.ratchetVersion(c.disableV2Ratchet) { + case 1: + r.MyIdentityPrivate = &c.identity + r.TheirIdentityPublic = &contact.theirIdentityPublic + case 2: + r.MyIdentityPrivate = new([32]byte) + extra25519.PrivateKeyToCurve25519(r.MyIdentityPrivate, &c.priv) + r.TheirIdentityPublic = new([32]byte) + extra25519.PublicKeyToCurve25519(r.TheirIdentityPublic, &contact.theirPub) + } return r } diff --git a/client/disk.go b/client/disk.go index 8406609..46161aa 100644 --- a/client/disk.go +++ b/client/disk.go @@ -11,6 +11,14 @@ import ( "golang.org/x/crypto/curve25519" ) +//go:generate protoc --proto_path=$GOPATH/src:. --gogo_out=. disk/client.proto + +// We use gogoprotobuf from https://code.google.com/p/gogoprotobuf/ because +// Francesc @Campoy indicated that even Google uses it over goprotobuf. +// See 29d5f5d16f523b0a113e786143fc4dacc8affa97 for goprotobuf scripts like : +// protoc --proto_path=$GOPATH/src:. --go_out=. disk/client.proto +// perl -p -i~ -e 's/(import protos \"github.com\/agl\/pond\/protos)\/pond.pb\"/$1\"/' disk/client.pb.go + // erasureRotationTime is the amount of time that we'll use a single erasure // storage value before rotating. const erasureRotationTime = 24 * time.Hour diff --git a/client/disk/client.pb.go b/client/disk/client.pb.go index 1f29160..2f8f809 100644 --- a/client/disk/client.pb.go +++ b/client/disk/client.pb.go @@ -1,65 +1,89 @@ -// Code generated by protoc-gen-go. -// source: github.com/agl/pond/client/disk/client.proto +// Code generated by protoc-gen-gogo. +// source: disk/client.proto // DO NOT EDIT! +/* +Package disk is a generated protocol buffer package. + +It is generated from these files: + disk/client.proto + +It has these top-level messages: + Header + Contact + RatchetState + Inbox + Outbox + Draft + State +*/ package disk -import proto "github.com/golang/protobuf/proto" -import json "encoding/json" +import proto "code.google.com/p/gogoprotobuf/proto" import math "math" import protos "github.com/agl/pond/protos" -// Reference proto, json, and math imports to suppress error if they are not otherwise used. +// Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal -var _ = &json.SyntaxError{} var _ = math.Inf +// Header is placed at the beginning of the state file and is *unencrypted and +// unauthenticated*. Its purpose is only to describe how to decrypt the +// remainder of the file. type Header struct { - NonceSmearCopies *int32 `protobuf:"varint,1,opt,name=nonce_smear_copies,def=1365" json:"nonce_smear_copies,omitempty"` - KdfSalt []byte `protobuf:"bytes,2,opt,name=kdf_salt" json:"kdf_salt,omitempty"` - Scrypt *Header_SCrypt `protobuf:"bytes,3,opt,name=scrypt" json:"scrypt,omitempty"` - TpmNvram *Header_TPM `protobuf:"bytes,4,opt,name=tpm_nvram" json:"tpm_nvram,omitempty"` - NoErasureStorage *bool `protobuf:"varint,5,opt,name=no_erasure_storage" json:"no_erasure_storage,omitempty"` - XXX_unrecognized []byte `json:"-"` + // nonce_smear_copies contains the number of copies of the nonce that + // follow the header. Each copy of the nonce is different and, XORed + // together, they result in the real nonce. The intent is that this may + // make recovery of old state files more difficult on HDDs. + NonceSmearCopies *int32 `protobuf:"varint,1,opt,name=nonce_smear_copies,def=1365" json:"nonce_smear_copies,omitempty"` + // kdf_salt contains the salt for the KDF function. + KdfSalt []byte `protobuf:"bytes,2,opt,name=kdf_salt" json:"kdf_salt,omitempty"` + Scrypt *Header_SCrypt `protobuf:"bytes,3,opt,name=scrypt" json:"scrypt,omitempty"` + TpmNvram *Header_TPM `protobuf:"bytes,4,opt,name=tpm_nvram" json:"tpm_nvram,omitempty"` + // no_erasure_storage exists to signal that there is no erasure storage + // for this state file, as opposed to the state file using a method + // that isn't recognised by the client. + NoErasureStorage *bool `protobuf:"varint,5,opt,name=no_erasure_storage" json:"no_erasure_storage,omitempty"` + XXX_unrecognized []byte `json:"-"` } -func (this *Header) Reset() { *this = Header{} } -func (this *Header) String() string { return proto.CompactTextString(this) } -func (*Header) ProtoMessage() {} +func (m *Header) Reset() { *m = Header{} } +func (m *Header) String() string { return proto.CompactTextString(m) } +func (*Header) ProtoMessage() {} const Default_Header_NonceSmearCopies int32 = 1365 -func (this *Header) GetNonceSmearCopies() int32 { - if this != nil && this.NonceSmearCopies != nil { - return *this.NonceSmearCopies +func (m *Header) GetNonceSmearCopies() int32 { + if m != nil && m.NonceSmearCopies != nil { + return *m.NonceSmearCopies } return Default_Header_NonceSmearCopies } -func (this *Header) GetKdfSalt() []byte { - if this != nil { - return this.KdfSalt +func (m *Header) GetKdfSalt() []byte { + if m != nil { + return m.KdfSalt } return nil } -func (this *Header) GetScrypt() *Header_SCrypt { - if this != nil { - return this.Scrypt +func (m *Header) GetScrypt() *Header_SCrypt { + if m != nil { + return m.Scrypt } return nil } -func (this *Header) GetTpmNvram() *Header_TPM { - if this != nil { - return this.TpmNvram +func (m *Header) GetTpmNvram() *Header_TPM { + if m != nil { + return m.TpmNvram } return nil } -func (this *Header) GetNoErasureStorage() bool { - if this != nil && this.NoErasureStorage != nil { - return *this.NoErasureStorage +func (m *Header) GetNoErasureStorage() bool { + if m != nil && m.NoErasureStorage != nil { + return *m.NoErasureStorage } return false } @@ -71,47 +95,48 @@ type Header_SCrypt struct { XXX_unrecognized []byte `json:"-"` } -func (this *Header_SCrypt) Reset() { *this = Header_SCrypt{} } -func (this *Header_SCrypt) String() string { return proto.CompactTextString(this) } -func (*Header_SCrypt) ProtoMessage() {} +func (m *Header_SCrypt) Reset() { *m = Header_SCrypt{} } +func (m *Header_SCrypt) String() string { return proto.CompactTextString(m) } +func (*Header_SCrypt) ProtoMessage() {} const Default_Header_SCrypt_N int32 = 32768 const Default_Header_SCrypt_R int32 = 16 const Default_Header_SCrypt_P int32 = 1 -func (this *Header_SCrypt) GetN() int32 { - if this != nil && this.N != nil { - return *this.N +func (m *Header_SCrypt) GetN() int32 { + if m != nil && m.N != nil { + return *m.N } return Default_Header_SCrypt_N } -func (this *Header_SCrypt) GetR() int32 { - if this != nil && this.R != nil { - return *this.R +func (m *Header_SCrypt) GetR() int32 { + if m != nil && m.R != nil { + return *m.R } return Default_Header_SCrypt_R } -func (this *Header_SCrypt) GetP() int32 { - if this != nil && this.P != nil { - return *this.P +func (m *Header_SCrypt) GetP() int32 { + if m != nil && m.P != nil { + return *m.P } return Default_Header_SCrypt_P } +// TPM contains information about an erasure key stored in TPM NVRAM. type Header_TPM struct { Index *uint32 `protobuf:"varint,1,req,name=index" json:"index,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (this *Header_TPM) Reset() { *this = Header_TPM{} } -func (this *Header_TPM) String() string { return proto.CompactTextString(this) } -func (*Header_TPM) ProtoMessage() {} +func (m *Header_TPM) Reset() { *m = Header_TPM{} } +func (m *Header_TPM) String() string { return proto.CompactTextString(m) } +func (*Header_TPM) ProtoMessage() {} -func (this *Header_TPM) GetIndex() uint32 { - if this != nil && this.Index != nil { - return *this.Index +func (m *Header_TPM) GetIndex() uint32 { + if m != nil && m.Index != nil { + return *m.Index } return 0 } @@ -142,162 +167,162 @@ type Contact struct { XXX_unrecognized []byte `json:"-"` } -func (this *Contact) Reset() { *this = Contact{} } -func (this *Contact) String() string { return proto.CompactTextString(this) } -func (*Contact) ProtoMessage() {} +func (m *Contact) Reset() { *m = Contact{} } +func (m *Contact) String() string { return proto.CompactTextString(m) } +func (*Contact) ProtoMessage() {} const Default_Contact_IsPending bool = false -func (this *Contact) GetId() uint64 { - if this != nil && this.Id != nil { - return *this.Id +func (m *Contact) GetId() uint64 { + if m != nil && m.Id != nil { + return *m.Id } return 0 } -func (this *Contact) GetName() string { - if this != nil && this.Name != nil { - return *this.Name +func (m *Contact) GetName() string { + if m != nil && m.Name != nil { + return *m.Name } return "" } -func (this *Contact) GetGroupKey() []byte { - if this != nil { - return this.GroupKey +func (m *Contact) GetGroupKey() []byte { + if m != nil { + return m.GroupKey } return nil } -func (this *Contact) GetSupportedVersion() int32 { - if this != nil && this.SupportedVersion != nil { - return *this.SupportedVersion +func (m *Contact) GetSupportedVersion() int32 { + if m != nil && m.SupportedVersion != nil { + return *m.SupportedVersion } return 0 } -func (this *Contact) GetKeyExchangeBytes() []byte { - if this != nil { - return this.KeyExchangeBytes +func (m *Contact) GetKeyExchangeBytes() []byte { + if m != nil { + return m.KeyExchangeBytes } return nil } -func (this *Contact) GetPandaKeyExchange() []byte { - if this != nil { - return this.PandaKeyExchange +func (m *Contact) GetPandaKeyExchange() []byte { + if m != nil { + return m.PandaKeyExchange } return nil } -func (this *Contact) GetPandaError() string { - if this != nil && this.PandaError != nil { - return *this.PandaError +func (m *Contact) GetPandaError() string { + if m != nil && m.PandaError != nil { + return *m.PandaError } return "" } -func (this *Contact) GetTheirGroup() []byte { - if this != nil { - return this.TheirGroup +func (m *Contact) GetTheirGroup() []byte { + if m != nil { + return m.TheirGroup } return nil } -func (this *Contact) GetMyGroupKey() []byte { - if this != nil { - return this.MyGroupKey +func (m *Contact) GetMyGroupKey() []byte { + if m != nil { + return m.MyGroupKey } return nil } -func (this *Contact) GetGeneration() uint32 { - if this != nil && this.Generation != nil { - return *this.Generation +func (m *Contact) GetGeneration() uint32 { + if m != nil && m.Generation != nil { + return *m.Generation } return 0 } -func (this *Contact) GetTheirServer() string { - if this != nil && this.TheirServer != nil { - return *this.TheirServer +func (m *Contact) GetTheirServer() string { + if m != nil && m.TheirServer != nil { + return *m.TheirServer } return "" } -func (this *Contact) GetTheirPub() []byte { - if this != nil { - return this.TheirPub +func (m *Contact) GetTheirPub() []byte { + if m != nil { + return m.TheirPub } return nil } -func (this *Contact) GetTheirIdentityPublic() []byte { - if this != nil { - return this.TheirIdentityPublic +func (m *Contact) GetTheirIdentityPublic() []byte { + if m != nil { + return m.TheirIdentityPublic } return nil } -func (this *Contact) GetRevokedUs() bool { - if this != nil && this.RevokedUs != nil { - return *this.RevokedUs +func (m *Contact) GetRevokedUs() bool { + if m != nil && m.RevokedUs != nil { + return *m.RevokedUs } return false } -func (this *Contact) GetLastPrivate() []byte { - if this != nil { - return this.LastPrivate +func (m *Contact) GetLastPrivate() []byte { + if m != nil { + return m.LastPrivate } return nil } -func (this *Contact) GetCurrentPrivate() []byte { - if this != nil { - return this.CurrentPrivate +func (m *Contact) GetCurrentPrivate() []byte { + if m != nil { + return m.CurrentPrivate } return nil } -func (this *Contact) GetTheirLastPublic() []byte { - if this != nil { - return this.TheirLastPublic +func (m *Contact) GetTheirLastPublic() []byte { + if m != nil { + return m.TheirLastPublic } return nil } -func (this *Contact) GetTheirCurrentPublic() []byte { - if this != nil { - return this.TheirCurrentPublic +func (m *Contact) GetTheirCurrentPublic() []byte { + if m != nil { + return m.TheirCurrentPublic } return nil } -func (this *Contact) GetRatchet() *RatchetState { - if this != nil { - return this.Ratchet +func (m *Contact) GetRatchet() *RatchetState { + if m != nil { + return m.Ratchet } return nil } -func (this *Contact) GetPreviousTags() []*Contact_PreviousTag { - if this != nil { - return this.PreviousTags +func (m *Contact) GetPreviousTags() []*Contact_PreviousTag { + if m != nil { + return m.PreviousTags } return nil } -func (this *Contact) GetEvents() []*Contact_Event { - if this != nil { - return this.Events +func (m *Contact) GetEvents() []*Contact_Event { + if m != nil { + return m.Events } return nil } -func (this *Contact) GetIsPending() bool { - if this != nil && this.IsPending != nil { - return *this.IsPending +func (m *Contact) GetIsPending() bool { + if m != nil && m.IsPending != nil { + return *m.IsPending } return Default_Contact_IsPending } @@ -308,20 +333,20 @@ type Contact_PreviousTag struct { XXX_unrecognized []byte `json:"-"` } -func (this *Contact_PreviousTag) Reset() { *this = Contact_PreviousTag{} } -func (this *Contact_PreviousTag) String() string { return proto.CompactTextString(this) } -func (*Contact_PreviousTag) ProtoMessage() {} +func (m *Contact_PreviousTag) Reset() { *m = Contact_PreviousTag{} } +func (m *Contact_PreviousTag) String() string { return proto.CompactTextString(m) } +func (*Contact_PreviousTag) ProtoMessage() {} -func (this *Contact_PreviousTag) GetTag() []byte { - if this != nil { - return this.Tag +func (m *Contact_PreviousTag) GetTag() []byte { + if m != nil { + return m.Tag } return nil } -func (this *Contact_PreviousTag) GetExpired() int64 { - if this != nil && this.Expired != nil { - return *this.Expired +func (m *Contact_PreviousTag) GetExpired() int64 { + if m != nil && m.Expired != nil { + return *m.Expired } return 0 } @@ -332,20 +357,20 @@ type Contact_Event struct { XXX_unrecognized []byte `json:"-"` } -func (this *Contact_Event) Reset() { *this = Contact_Event{} } -func (this *Contact_Event) String() string { return proto.CompactTextString(this) } -func (*Contact_Event) ProtoMessage() {} +func (m *Contact_Event) Reset() { *m = Contact_Event{} } +func (m *Contact_Event) String() string { return proto.CompactTextString(m) } +func (*Contact_Event) ProtoMessage() {} -func (this *Contact_Event) GetTime() int64 { - if this != nil && this.Time != nil { - return *this.Time +func (m *Contact_Event) GetTime() int64 { + if m != nil && m.Time != nil { + return *m.Time } return 0 } -func (this *Contact_Event) GetMessage() string { - if this != nil && this.Message != nil { - return *this.Message +func (m *Contact_Event) GetMessage() string { + if m != nil && m.Message != nil { + return *m.Message } return "" } @@ -371,125 +396,125 @@ type RatchetState struct { XXX_unrecognized []byte `json:"-"` } -func (this *RatchetState) Reset() { *this = RatchetState{} } -func (this *RatchetState) String() string { return proto.CompactTextString(this) } -func (*RatchetState) ProtoMessage() {} +func (m *RatchetState) Reset() { *m = RatchetState{} } +func (m *RatchetState) String() string { return proto.CompactTextString(m) } +func (*RatchetState) ProtoMessage() {} -func (this *RatchetState) GetRootKey() []byte { - if this != nil { - return this.RootKey +func (m *RatchetState) GetRootKey() []byte { + if m != nil { + return m.RootKey } return nil } -func (this *RatchetState) GetSendHeaderKey() []byte { - if this != nil { - return this.SendHeaderKey +func (m *RatchetState) GetSendHeaderKey() []byte { + if m != nil { + return m.SendHeaderKey } return nil } -func (this *RatchetState) GetRecvHeaderKey() []byte { - if this != nil { - return this.RecvHeaderKey +func (m *RatchetState) GetRecvHeaderKey() []byte { + if m != nil { + return m.RecvHeaderKey } return nil } -func (this *RatchetState) GetNextSendHeaderKey() []byte { - if this != nil { - return this.NextSendHeaderKey +func (m *RatchetState) GetNextSendHeaderKey() []byte { + if m != nil { + return m.NextSendHeaderKey } return nil } -func (this *RatchetState) GetNextRecvHeaderKey() []byte { - if this != nil { - return this.NextRecvHeaderKey +func (m *RatchetState) GetNextRecvHeaderKey() []byte { + if m != nil { + return m.NextRecvHeaderKey } return nil } -func (this *RatchetState) GetSendChainKey() []byte { - if this != nil { - return this.SendChainKey +func (m *RatchetState) GetSendChainKey() []byte { + if m != nil { + return m.SendChainKey } return nil } -func (this *RatchetState) GetRecvChainKey() []byte { - if this != nil { - return this.RecvChainKey +func (m *RatchetState) GetRecvChainKey() []byte { + if m != nil { + return m.RecvChainKey } return nil } -func (this *RatchetState) GetSendRatchetPrivate() []byte { - if this != nil { - return this.SendRatchetPrivate +func (m *RatchetState) GetSendRatchetPrivate() []byte { + if m != nil { + return m.SendRatchetPrivate } return nil } -func (this *RatchetState) GetRecvRatchetPublic() []byte { - if this != nil { - return this.RecvRatchetPublic +func (m *RatchetState) GetRecvRatchetPublic() []byte { + if m != nil { + return m.RecvRatchetPublic } return nil } -func (this *RatchetState) GetSendCount() uint32 { - if this != nil && this.SendCount != nil { - return *this.SendCount +func (m *RatchetState) GetSendCount() uint32 { + if m != nil && m.SendCount != nil { + return *m.SendCount } return 0 } -func (this *RatchetState) GetRecvCount() uint32 { - if this != nil && this.RecvCount != nil { - return *this.RecvCount +func (m *RatchetState) GetRecvCount() uint32 { + if m != nil && m.RecvCount != nil { + return *m.RecvCount } return 0 } -func (this *RatchetState) GetPrevSendCount() uint32 { - if this != nil && this.PrevSendCount != nil { - return *this.PrevSendCount +func (m *RatchetState) GetPrevSendCount() uint32 { + if m != nil && m.PrevSendCount != nil { + return *m.PrevSendCount } return 0 } -func (this *RatchetState) GetRatchet() bool { - if this != nil && this.Ratchet != nil { - return *this.Ratchet +func (m *RatchetState) GetRatchet() bool { + if m != nil && m.Ratchet != nil { + return *m.Ratchet } return false } -func (this *RatchetState) GetV2() bool { - if this != nil && this.V2 != nil { - return *this.V2 +func (m *RatchetState) GetV2() bool { + if m != nil && m.V2 != nil { + return *m.V2 } return false } -func (this *RatchetState) GetPrivate0() []byte { - if this != nil { - return this.Private0 +func (m *RatchetState) GetPrivate0() []byte { + if m != nil { + return m.Private0 } return nil } -func (this *RatchetState) GetPrivate1() []byte { - if this != nil { - return this.Private1 +func (m *RatchetState) GetPrivate1() []byte { + if m != nil { + return m.Private1 } return nil } -func (this *RatchetState) GetSavedKeys() []*RatchetState_SavedKeys { - if this != nil { - return this.SavedKeys +func (m *RatchetState) GetSavedKeys() []*RatchetState_SavedKeys { + if m != nil { + return m.SavedKeys } return nil } @@ -500,20 +525,20 @@ type RatchetState_SavedKeys struct { XXX_unrecognized []byte `json:"-"` } -func (this *RatchetState_SavedKeys) Reset() { *this = RatchetState_SavedKeys{} } -func (this *RatchetState_SavedKeys) String() string { return proto.CompactTextString(this) } -func (*RatchetState_SavedKeys) ProtoMessage() {} +func (m *RatchetState_SavedKeys) Reset() { *m = RatchetState_SavedKeys{} } +func (m *RatchetState_SavedKeys) String() string { return proto.CompactTextString(m) } +func (*RatchetState_SavedKeys) ProtoMessage() {} -func (this *RatchetState_SavedKeys) GetHeaderKey() []byte { - if this != nil { - return this.HeaderKey +func (m *RatchetState_SavedKeys) GetHeaderKey() []byte { + if m != nil { + return m.HeaderKey } return nil } -func (this *RatchetState_SavedKeys) GetMessageKeys() []*RatchetState_SavedKeys_MessageKey { - if this != nil { - return this.MessageKeys +func (m *RatchetState_SavedKeys) GetMessageKeys() []*RatchetState_SavedKeys_MessageKey { + if m != nil { + return m.MessageKeys } return nil } @@ -525,27 +550,27 @@ type RatchetState_SavedKeys_MessageKey struct { XXX_unrecognized []byte `json:"-"` } -func (this *RatchetState_SavedKeys_MessageKey) Reset() { *this = RatchetState_SavedKeys_MessageKey{} } -func (this *RatchetState_SavedKeys_MessageKey) String() string { return proto.CompactTextString(this) } -func (*RatchetState_SavedKeys_MessageKey) ProtoMessage() {} +func (m *RatchetState_SavedKeys_MessageKey) Reset() { *m = RatchetState_SavedKeys_MessageKey{} } +func (m *RatchetState_SavedKeys_MessageKey) String() string { return proto.CompactTextString(m) } +func (*RatchetState_SavedKeys_MessageKey) ProtoMessage() {} -func (this *RatchetState_SavedKeys_MessageKey) GetNum() uint32 { - if this != nil && this.Num != nil { - return *this.Num +func (m *RatchetState_SavedKeys_MessageKey) GetNum() uint32 { + if m != nil && m.Num != nil { + return *m.Num } return 0 } -func (this *RatchetState_SavedKeys_MessageKey) GetKey() []byte { - if this != nil { - return this.Key +func (m *RatchetState_SavedKeys_MessageKey) GetKey() []byte { + if m != nil { + return m.Key } return nil } -func (this *RatchetState_SavedKeys_MessageKey) GetCreationTime() int64 { - if this != nil && this.CreationTime != nil { - return *this.CreationTime +func (m *RatchetState_SavedKeys_MessageKey) GetCreationTime() int64 { + if m != nil && m.CreationTime != nil { + return *m.CreationTime } return 0 } @@ -562,64 +587,64 @@ type Inbox struct { XXX_unrecognized []byte `json:"-"` } -func (this *Inbox) Reset() { *this = Inbox{} } -func (this *Inbox) String() string { return proto.CompactTextString(this) } -func (*Inbox) ProtoMessage() {} +func (m *Inbox) Reset() { *m = Inbox{} } +func (m *Inbox) String() string { return proto.CompactTextString(m) } +func (*Inbox) ProtoMessage() {} const Default_Inbox_Retained bool = false -func (this *Inbox) GetId() uint64 { - if this != nil && this.Id != nil { - return *this.Id +func (m *Inbox) GetId() uint64 { + if m != nil && m.Id != nil { + return *m.Id } return 0 } -func (this *Inbox) GetFrom() uint64 { - if this != nil && this.From != nil { - return *this.From +func (m *Inbox) GetFrom() uint64 { + if m != nil && m.From != nil { + return *m.From } return 0 } -func (this *Inbox) GetReceivedTime() int64 { - if this != nil && this.ReceivedTime != nil { - return *this.ReceivedTime +func (m *Inbox) GetReceivedTime() int64 { + if m != nil && m.ReceivedTime != nil { + return *m.ReceivedTime } return 0 } -func (this *Inbox) GetAcked() bool { - if this != nil && this.Acked != nil { - return *this.Acked +func (m *Inbox) GetAcked() bool { + if m != nil && m.Acked != nil { + return *m.Acked } return false } -func (this *Inbox) GetMessage() []byte { - if this != nil { - return this.Message +func (m *Inbox) GetMessage() []byte { + if m != nil { + return m.Message } return nil } -func (this *Inbox) GetRead() bool { - if this != nil && this.Read != nil { - return *this.Read +func (m *Inbox) GetRead() bool { + if m != nil && m.Read != nil { + return *m.Read } return false } -func (this *Inbox) GetSealed() []byte { - if this != nil { - return this.Sealed +func (m *Inbox) GetSealed() []byte { + if m != nil { + return m.Sealed } return nil } -func (this *Inbox) GetRetained() bool { - if this != nil && this.Retained != nil { - return *this.Retained +func (m *Inbox) GetRetained() bool { + if m != nil && m.Retained != nil { + return *m.Retained } return Default_Inbox_Retained } @@ -637,69 +662,69 @@ type Outbox struct { XXX_unrecognized []byte `json:"-"` } -func (this *Outbox) Reset() { *this = Outbox{} } -func (this *Outbox) String() string { return proto.CompactTextString(this) } -func (*Outbox) ProtoMessage() {} +func (m *Outbox) Reset() { *m = Outbox{} } +func (m *Outbox) String() string { return proto.CompactTextString(m) } +func (*Outbox) ProtoMessage() {} -func (this *Outbox) GetId() uint64 { - if this != nil && this.Id != nil { - return *this.Id +func (m *Outbox) GetId() uint64 { + if m != nil && m.Id != nil { + return *m.Id } return 0 } -func (this *Outbox) GetTo() uint64 { - if this != nil && this.To != nil { - return *this.To +func (m *Outbox) GetTo() uint64 { + if m != nil && m.To != nil { + return *m.To } return 0 } -func (this *Outbox) GetServer() string { - if this != nil && this.Server != nil { - return *this.Server +func (m *Outbox) GetServer() string { + if m != nil && m.Server != nil { + return *m.Server } return "" } -func (this *Outbox) GetCreated() int64 { - if this != nil && this.Created != nil { - return *this.Created +func (m *Outbox) GetCreated() int64 { + if m != nil && m.Created != nil { + return *m.Created } return 0 } -func (this *Outbox) GetSent() int64 { - if this != nil && this.Sent != nil { - return *this.Sent +func (m *Outbox) GetSent() int64 { + if m != nil && m.Sent != nil { + return *m.Sent } return 0 } -func (this *Outbox) GetMessage() []byte { - if this != nil { - return this.Message +func (m *Outbox) GetMessage() []byte { + if m != nil { + return m.Message } return nil } -func (this *Outbox) GetRequest() []byte { - if this != nil { - return this.Request +func (m *Outbox) GetRequest() []byte { + if m != nil { + return m.Request } return nil } -func (this *Outbox) GetAcked() int64 { - if this != nil && this.Acked != nil { - return *this.Acked +func (m *Outbox) GetAcked() int64 { + if m != nil && m.Acked != nil { + return *m.Acked } return 0 } -func (this *Outbox) GetRevocation() bool { - if this != nil && this.Revocation != nil { - return *this.Revocation +func (m *Outbox) GetRevocation() bool { + if m != nil && m.Revocation != nil { + return *m.Revocation } return false } @@ -715,55 +740,55 @@ type Draft struct { XXX_unrecognized []byte `json:"-"` } -func (this *Draft) Reset() { *this = Draft{} } -func (this *Draft) String() string { return proto.CompactTextString(this) } -func (*Draft) ProtoMessage() {} +func (m *Draft) Reset() { *m = Draft{} } +func (m *Draft) String() string { return proto.CompactTextString(m) } +func (*Draft) ProtoMessage() {} -func (this *Draft) GetId() uint64 { - if this != nil && this.Id != nil { - return *this.Id +func (m *Draft) GetId() uint64 { + if m != nil && m.Id != nil { + return *m.Id } return 0 } -func (this *Draft) GetCreated() int64 { - if this != nil && this.Created != nil { - return *this.Created +func (m *Draft) GetCreated() int64 { + if m != nil && m.Created != nil { + return *m.Created } return 0 } -func (this *Draft) GetTo() uint64 { - if this != nil && this.To != nil { - return *this.To +func (m *Draft) GetTo() uint64 { + if m != nil && m.To != nil { + return *m.To } return 0 } -func (this *Draft) GetBody() string { - if this != nil && this.Body != nil { - return *this.Body +func (m *Draft) GetBody() string { + if m != nil && m.Body != nil { + return *m.Body } return "" } -func (this *Draft) GetInReplyTo() uint64 { - if this != nil && this.InReplyTo != nil { - return *this.InReplyTo +func (m *Draft) GetInReplyTo() uint64 { + if m != nil && m.InReplyTo != nil { + return *m.InReplyTo } return 0 } -func (this *Draft) GetAttachments() []*protos.Message_Attachment { - if this != nil { - return this.Attachments +func (m *Draft) GetAttachments() []*protos.Message_Attachment { + if m != nil { + return m.Attachments } return nil } -func (this *Draft) GetDetachments() []*protos.Message_Detachment { - if this != nil { - return this.Detachments +func (m *Draft) GetDetachments() []*protos.Message_Detachment { + if m != nil { + return m.Detachments } return nil } @@ -785,97 +810,97 @@ type State struct { XXX_unrecognized []byte `json:"-"` } -func (this *State) Reset() { *this = State{} } -func (this *State) String() string { return proto.CompactTextString(this) } -func (*State) ProtoMessage() {} +func (m *State) Reset() { *m = State{} } +func (m *State) String() string { return proto.CompactTextString(m) } +func (*State) ProtoMessage() {} -func (this *State) GetIdentity() []byte { - if this != nil { - return this.Identity +func (m *State) GetIdentity() []byte { + if m != nil { + return m.Identity } return nil } -func (this *State) GetPublic() []byte { - if this != nil { - return this.Public +func (m *State) GetPublic() []byte { + if m != nil { + return m.Public } return nil } -func (this *State) GetPrivate() []byte { - if this != nil { - return this.Private +func (m *State) GetPrivate() []byte { + if m != nil { + return m.Private } return nil } -func (this *State) GetServer() string { - if this != nil && this.Server != nil { - return *this.Server +func (m *State) GetServer() string { + if m != nil && m.Server != nil { + return *m.Server } return "" } -func (this *State) GetGroup() []byte { - if this != nil { - return this.Group +func (m *State) GetGroup() []byte { + if m != nil { + return m.Group } return nil } -func (this *State) GetGroupPrivate() []byte { - if this != nil { - return this.GroupPrivate +func (m *State) GetGroupPrivate() []byte { + if m != nil { + return m.GroupPrivate } return nil } -func (this *State) GetPreviousGroupPrivateKeys() []*State_PreviousGroup { - if this != nil { - return this.PreviousGroupPrivateKeys +func (m *State) GetPreviousGroupPrivateKeys() []*State_PreviousGroup { + if m != nil { + return m.PreviousGroupPrivateKeys } return nil } -func (this *State) GetGeneration() uint32 { - if this != nil && this.Generation != nil { - return *this.Generation +func (m *State) GetGeneration() uint32 { + if m != nil && m.Generation != nil { + return *m.Generation } return 0 } -func (this *State) GetLastErasureStorageTime() int64 { - if this != nil && this.LastErasureStorageTime != nil { - return *this.LastErasureStorageTime +func (m *State) GetLastErasureStorageTime() int64 { + if m != nil && m.LastErasureStorageTime != nil { + return *m.LastErasureStorageTime } return 0 } -func (this *State) GetContacts() []*Contact { - if this != nil { - return this.Contacts +func (m *State) GetContacts() []*Contact { + if m != nil { + return m.Contacts } return nil } -func (this *State) GetInbox() []*Inbox { - if this != nil { - return this.Inbox +func (m *State) GetInbox() []*Inbox { + if m != nil { + return m.Inbox } return nil } -func (this *State) GetOutbox() []*Outbox { - if this != nil { - return this.Outbox +func (m *State) GetOutbox() []*Outbox { + if m != nil { + return m.Outbox } return nil } -func (this *State) GetDrafts() []*Draft { - if this != nil { - return this.Drafts +func (m *State) GetDrafts() []*Draft { + if m != nil { + return m.Drafts } return nil } @@ -887,27 +912,27 @@ type State_PreviousGroup struct { XXX_unrecognized []byte `json:"-"` } -func (this *State_PreviousGroup) Reset() { *this = State_PreviousGroup{} } -func (this *State_PreviousGroup) String() string { return proto.CompactTextString(this) } -func (*State_PreviousGroup) ProtoMessage() {} +func (m *State_PreviousGroup) Reset() { *m = State_PreviousGroup{} } +func (m *State_PreviousGroup) String() string { return proto.CompactTextString(m) } +func (*State_PreviousGroup) ProtoMessage() {} -func (this *State_PreviousGroup) GetGroup() []byte { - if this != nil { - return this.Group +func (m *State_PreviousGroup) GetGroup() []byte { + if m != nil { + return m.Group } return nil } -func (this *State_PreviousGroup) GetGroupPrivate() []byte { - if this != nil { - return this.GroupPrivate +func (m *State_PreviousGroup) GetGroupPrivate() []byte { + if m != nil { + return m.GroupPrivate } return nil } -func (this *State_PreviousGroup) GetExpired() int64 { - if this != nil && this.Expired != nil { - return *this.Expired +func (m *State_PreviousGroup) GetExpired() int64 { + if m != nil && m.Expired != nil { + return *m.Expired } return 0 } diff --git a/client/erasure_gui.go b/client/erasure_gui.go new file mode 100644 index 0000000..016fada --- /dev/null +++ b/client/erasure_gui.go @@ -0,0 +1,16 @@ +// +build !nogui,!linux + +// Any build options that posses their own createErasureStorage should be excluded above. + +package main + +import ( + "github.com/agl/pond/client/disk" +) + +func (c *guiClient) createErasureStorage(pw string, stateFile *disk.StateFile) error { + c.gui.Actions() <- UIState{uiStateErasureStorage} + c.gui.Signal() + + return c.client.createErasureStorage(pw, stateFile) +} diff --git a/client/gui.go b/client/gui.go index 7d96a5f..eec8d83 100644 --- a/client/gui.go +++ b/client/gui.go @@ -1897,8 +1897,9 @@ func nameValuesLHS(entries []nvEntry) Grid { func (c *guiClient) identityUI() interface{} { entries := nameValuesLHS([]nvEntry{ {"SERVER", c.server}, - {"PUBLIC IDENTITY", fmt.Sprintf("%x", c.identityPublic[:])}, + {"FINGERPRINT", fmt.Sprintf("%x", c.fingerprint())}, {"PUBLIC KEY", fmt.Sprintf("%x", c.pub[:])}, + {"IDENTITY KEY", fmt.Sprintf("%x", c.identityPublic[:])}, {"STATE FILE", c.stateFilename}, {"GROUP GENERATION", fmt.Sprintf("%d", c.generation)}, }) @@ -2067,8 +2068,9 @@ func (c *guiClient) showContact(id uint64) interface{} { entries := []nvEntry{ {"NAME", ""}, {"SERVER", contact.theirServer}, - {"PUBLIC IDENTITY", fmt.Sprintf("%x", contact.theirIdentityPublic[:])}, + {"FINGERPRINT", fmt.Sprintf("%x", contact.fingerprint())}, {"PUBLIC KEY", fmt.Sprintf("%x", contact.theirPub[:])}, + {"IDENTITY KEY", fmt.Sprintf("%x", contact.theirIdentityPublic[:])}, } if !allBytesZero(contact.theirLastDHPublic[:]) { entries = append(entries, diff --git a/client/network.go b/client/network.go index 673e3c0..64c954b 100644 --- a/client/network.go +++ b/client/network.go @@ -153,6 +153,14 @@ func tooLarge(msg *queuedMessage) bool { return len(messageBytes) > pond.MaxSerializedMessage } +func fingerprint(s ...[]byte) []byte { + sha := sha256.New() + for _, x := range s { + sha.Write(x) + } + return sha.Sum(nil) +} + // processSigningRequest is run on the main goroutine in response to a request // from the network thread to apply a group signature to a message that is just // about to be sent to the destination server. diff --git a/panda/panda.go b/panda/panda.go index 5e701e7..efc1330 100644 --- a/panda/panda.go +++ b/panda/panda.go @@ -24,6 +24,8 @@ import ( panda_proto "github.com/agl/pond/panda/proto" ) +//go:generate protoc --proto_path=$GOPATH/src:. --gogo_out=. proto/core.proto + const ( generatedSecretStringPrefix = "r!" // generatedSecretStringPrefix2 is used to indicate that scrypt should diff --git a/panda/proto/core.pb.go b/panda/proto/core.pb.go index be3f4ff..b81b18d 100644 --- a/panda/proto/core.pb.go +++ b/panda/proto/core.pb.go @@ -1,16 +1,23 @@ -// Code generated by protoc-gen-go. -// source: github.com/agl/pond/panda/proto/core.proto +// Code generated by protoc-gen-gogo. +// source: proto/core.proto // DO NOT EDIT! +/* +Package panda is a generated protocol buffer package. + +It is generated from these files: + proto/core.proto + +It has these top-level messages: + KeyExchange +*/ package panda -import proto "github.com/golang/protobuf/proto" -import json "encoding/json" +import proto "code.google.com/p/gogoprotobuf/proto" import math "math" -// Reference proto, json, and math imports to suppress error if they are not otherwise used. +// Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal -var _ = &json.SyntaxError{} var _ = math.Inf type KeyExchange_Status int32 @@ -40,9 +47,6 @@ func (x KeyExchange_Status) Enum() *KeyExchange_Status { func (x KeyExchange_Status) String() string { return proto.EnumName(KeyExchange_Status_name, int32(x)) } -func (x KeyExchange_Status) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *KeyExchange_Status) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(KeyExchange_Status_value, data, "KeyExchange_Status") if err != nil { @@ -66,76 +70,76 @@ type KeyExchange struct { XXX_unrecognized []byte `json:"-"` } -func (this *KeyExchange) Reset() { *this = KeyExchange{} } -func (this *KeyExchange) String() string { return proto.CompactTextString(this) } -func (*KeyExchange) ProtoMessage() {} +func (m *KeyExchange) Reset() { *m = KeyExchange{} } +func (m *KeyExchange) String() string { return proto.CompactTextString(m) } +func (*KeyExchange) ProtoMessage() {} -func (this *KeyExchange) GetStatus() KeyExchange_Status { - if this != nil && this.Status != nil { - return *this.Status +func (m *KeyExchange) GetStatus() KeyExchange_Status { + if m != nil && m.Status != nil { + return *m.Status } - return 0 + return KeyExchange_INIT } -func (this *KeyExchange) GetKeyExchangeBytes() []byte { - if this != nil { - return this.KeyExchangeBytes +func (m *KeyExchange) GetKeyExchangeBytes() []byte { + if m != nil { + return m.KeyExchangeBytes } return nil } -func (this *KeyExchange) GetSharedSecret() *KeyExchange_SharedSecret { - if this != nil { - return this.SharedSecret +func (m *KeyExchange) GetSharedSecret() *KeyExchange_SharedSecret { + if m != nil { + return m.SharedSecret } return nil } -func (this *KeyExchange) GetDhPrivate() []byte { - if this != nil { - return this.DhPrivate +func (m *KeyExchange) GetDhPrivate() []byte { + if m != nil { + return m.DhPrivate } return nil } -func (this *KeyExchange) GetKey() []byte { - if this != nil { - return this.Key +func (m *KeyExchange) GetKey() []byte { + if m != nil { + return m.Key } return nil } -func (this *KeyExchange) GetMeeting1() []byte { - if this != nil { - return this.Meeting1 +func (m *KeyExchange) GetMeeting1() []byte { + if m != nil { + return m.Meeting1 } return nil } -func (this *KeyExchange) GetMeeting2() []byte { - if this != nil { - return this.Meeting2 +func (m *KeyExchange) GetMeeting2() []byte { + if m != nil { + return m.Meeting2 } return nil } -func (this *KeyExchange) GetMessage1() []byte { - if this != nil { - return this.Message1 +func (m *KeyExchange) GetMessage1() []byte { + if m != nil { + return m.Message1 } return nil } -func (this *KeyExchange) GetMessage2() []byte { - if this != nil { - return this.Message2 +func (m *KeyExchange) GetMessage2() []byte { + if m != nil { + return m.Message2 } return nil } -func (this *KeyExchange) GetSharedKey() []byte { - if this != nil { - return this.SharedKey +func (m *KeyExchange) GetSharedKey() []byte { + if m != nil { + return m.SharedKey } return nil } @@ -148,34 +152,34 @@ type KeyExchange_SharedSecret struct { XXX_unrecognized []byte `json:"-"` } -func (this *KeyExchange_SharedSecret) Reset() { *this = KeyExchange_SharedSecret{} } -func (this *KeyExchange_SharedSecret) String() string { return proto.CompactTextString(this) } -func (*KeyExchange_SharedSecret) ProtoMessage() {} +func (m *KeyExchange_SharedSecret) Reset() { *m = KeyExchange_SharedSecret{} } +func (m *KeyExchange_SharedSecret) String() string { return proto.CompactTextString(m) } +func (*KeyExchange_SharedSecret) ProtoMessage() {} -func (this *KeyExchange_SharedSecret) GetSecret() string { - if this != nil && this.Secret != nil { - return *this.Secret +func (m *KeyExchange_SharedSecret) GetSecret() string { + if m != nil && m.Secret != nil { + return *m.Secret } return "" } -func (this *KeyExchange_SharedSecret) GetNumDecks() int32 { - if this != nil && this.NumDecks != nil { - return *this.NumDecks +func (m *KeyExchange_SharedSecret) GetNumDecks() int32 { + if m != nil && m.NumDecks != nil { + return *m.NumDecks } return 0 } -func (this *KeyExchange_SharedSecret) GetCardCount() []int32 { - if this != nil { - return this.CardCount +func (m *KeyExchange_SharedSecret) GetCardCount() []int32 { + if m != nil { + return m.CardCount } return nil } -func (this *KeyExchange_SharedSecret) GetTime() *KeyExchange_SharedSecret_Time { - if this != nil { - return this.Time +func (m *KeyExchange_SharedSecret) GetTime() *KeyExchange_SharedSecret_Time { + if m != nil { + return m.Time } return nil } @@ -189,41 +193,41 @@ type KeyExchange_SharedSecret_Time struct { XXX_unrecognized []byte `json:"-"` } -func (this *KeyExchange_SharedSecret_Time) Reset() { *this = KeyExchange_SharedSecret_Time{} } -func (this *KeyExchange_SharedSecret_Time) String() string { return proto.CompactTextString(this) } -func (*KeyExchange_SharedSecret_Time) ProtoMessage() {} +func (m *KeyExchange_SharedSecret_Time) Reset() { *m = KeyExchange_SharedSecret_Time{} } +func (m *KeyExchange_SharedSecret_Time) String() string { return proto.CompactTextString(m) } +func (*KeyExchange_SharedSecret_Time) ProtoMessage() {} -func (this *KeyExchange_SharedSecret_Time) GetDay() int32 { - if this != nil && this.Day != nil { - return *this.Day +func (m *KeyExchange_SharedSecret_Time) GetDay() int32 { + if m != nil && m.Day != nil { + return *m.Day } return 0 } -func (this *KeyExchange_SharedSecret_Time) GetMonth() int32 { - if this != nil && this.Month != nil { - return *this.Month +func (m *KeyExchange_SharedSecret_Time) GetMonth() int32 { + if m != nil && m.Month != nil { + return *m.Month } return 0 } -func (this *KeyExchange_SharedSecret_Time) GetYear() int32 { - if this != nil && this.Year != nil { - return *this.Year +func (m *KeyExchange_SharedSecret_Time) GetYear() int32 { + if m != nil && m.Year != nil { + return *m.Year } return 0 } -func (this *KeyExchange_SharedSecret_Time) GetHours() int32 { - if this != nil && this.Hours != nil { - return *this.Hours +func (m *KeyExchange_SharedSecret_Time) GetHours() int32 { + if m != nil && m.Hours != nil { + return *m.Hours } return 0 } -func (this *KeyExchange_SharedSecret_Time) GetMinutes() int32 { - if this != nil && this.Minutes != nil { - return *this.Minutes +func (m *KeyExchange_SharedSecret_Time) GetMinutes() int32 { + if m != nil && m.Minutes != nil { + return *m.Minutes } return 0 } diff --git a/protos/const.go b/protos/const.go index 233826d..44535ee 100644 --- a/protos/const.go +++ b/protos/const.go @@ -2,6 +2,8 @@ package protos import "golang.org/x/crypto/nacl/secretbox" +//go:generate protoc --proto_path=$GOPATH/src:. --gogo_out=. pond.proto + // TransportSize is the number of bytes that all payloads are padded to before // sending on the network. const TransportSize = 16384 - 2 - secretbox.Overhead diff --git a/protos/pond.pb.go b/protos/pond.pb.go index 0248192..248fc2e 100644 --- a/protos/pond.pb.go +++ b/protos/pond.pb.go @@ -1,16 +1,41 @@ -// Code generated by protoc-gen-go. -// source: github.com/agl/pond/protos/pond.proto +// Code generated by protoc-gen-gogo. +// source: pond.proto // DO NOT EDIT! +/* +Package protos is a generated protocol buffer package. + +It is generated from these files: + pond.proto + +It has these top-level messages: + Request + Reply + NewAccount + AccountDetails + AccountCreated + Delivery + Fetch + Fetched + ServerAnnounce + Upload + UploadReply + Download + DownloadReply + SignedRevocation + HMACSetup + HMACStrike + KeyExchange + SignedKeyExchange + Message +*/ package protos -import proto "github.com/golang/protobuf/proto" -import json "encoding/json" +import proto "code.google.com/p/gogoprotobuf/proto" import math "math" -// Reference proto, json, and math imports to suppress error if they are not otherwise used. +// Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal -var _ = &json.SyntaxError{} var _ = math.Inf type Reply_Status int32 @@ -34,12 +59,25 @@ const ( Reply_RESUME_PAST_END_OF_FILE Reply_Status = 21 Reply_GENERATION_REVOKED Reply_Status = 22 Reply_CANNOT_PARSE_REVOCATION Reply_Status = 23 - Reply_REGISTRATION_DISABLED Reply_Status = 24 - Reply_HMAC_KEY_ALREADY_SET Reply_Status = 25 - Reply_HMAC_NOT_SETUP Reply_Status = 26 - Reply_HMAC_INCORRECT Reply_Status = 27 - Reply_HMAC_USED Reply_Status = 28 - Reply_HMAC_REVOKED Reply_Status = 29 + // REGISTRATION_DISABLED may be returned after a NewAccount + // request to indicate the the server doesn't accept new + // registrations. + Reply_REGISTRATION_DISABLED Reply_Status = 24 + // HMAC_KEY_ALREADY_SET is returned in reply to a HMACSetup + // request if a different HMAC key has already been setup. + Reply_HMAC_KEY_ALREADY_SET Reply_Status = 25 + // HMAC_NOT_SETUP results from a delivery attempt when the + // recipient hasn't configured an HMAC key. + Reply_HMAC_NOT_SETUP Reply_Status = 26 + // HMAC_INCORRECT results from a delivery when the HMAC of the + // one-time public key doesn't validate. + Reply_HMAC_INCORRECT Reply_Status = 27 + // HMAC_USED results from a delivery when the HMAC value has + // already been used. + Reply_HMAC_USED Reply_Status = 28 + // HMAC_REVOKED results from a delivery when the HMAC value has + // been marked as revoked. + Reply_HMAC_REVOKED Reply_Status = 29 ) var Reply_Status_name = map[int32]string{ @@ -103,9 +141,6 @@ func (x Reply_Status) Enum() *Reply_Status { func (x Reply_Status) String() string { return proto.EnumName(Reply_Status_name, int32(x)) } -func (x Reply_Status) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *Reply_Status) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(Reply_Status_value, data, "Reply_Status") if err != nil { @@ -139,9 +174,6 @@ func (x Message_Encoding) Enum() *Message_Encoding { func (x Message_Encoding) String() string { return proto.EnumName(Message_Encoding_name, int32(x)) } -func (x Message_Encoding) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *Message_Encoding) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(Message_Encoding_value, data, "Message_Encoding") if err != nil { @@ -151,6 +183,8 @@ func (x *Message_Encoding) UnmarshalJSON(data []byte) error { return nil } +// Request is the client's request to the server. Only one of the optional +// messages may be present in any Request. type Request struct { NewAccount *NewAccount `protobuf:"bytes,1,opt,name=new_account" json:"new_account,omitempty"` Deliver *Delivery `protobuf:"bytes,2,opt,name=deliver" json:"deliver,omitempty"` @@ -163,66 +197,67 @@ type Request struct { XXX_unrecognized []byte `json:"-"` } -func (this *Request) Reset() { *this = Request{} } -func (this *Request) String() string { return proto.CompactTextString(this) } -func (*Request) ProtoMessage() {} +func (m *Request) Reset() { *m = Request{} } +func (m *Request) String() string { return proto.CompactTextString(m) } +func (*Request) ProtoMessage() {} -func (this *Request) GetNewAccount() *NewAccount { - if this != nil { - return this.NewAccount +func (m *Request) GetNewAccount() *NewAccount { + if m != nil { + return m.NewAccount } return nil } -func (this *Request) GetDeliver() *Delivery { - if this != nil { - return this.Deliver +func (m *Request) GetDeliver() *Delivery { + if m != nil { + return m.Deliver } return nil } -func (this *Request) GetFetch() *Fetch { - if this != nil { - return this.Fetch +func (m *Request) GetFetch() *Fetch { + if m != nil { + return m.Fetch } return nil } -func (this *Request) GetUpload() *Upload { - if this != nil { - return this.Upload +func (m *Request) GetUpload() *Upload { + if m != nil { + return m.Upload } return nil } -func (this *Request) GetDownload() *Download { - if this != nil { - return this.Download +func (m *Request) GetDownload() *Download { + if m != nil { + return m.Download } return nil } -func (this *Request) GetRevocation() *SignedRevocation { - if this != nil { - return this.Revocation +func (m *Request) GetRevocation() *SignedRevocation { + if m != nil { + return m.Revocation } return nil } -func (this *Request) GetHmacSetup() *HMACSetup { - if this != nil { - return this.HmacSetup +func (m *Request) GetHmacSetup() *HMACSetup { + if m != nil { + return m.HmacSetup } return nil } -func (this *Request) GetHmacStrike() *HMACStrike { - if this != nil { - return this.HmacStrike +func (m *Request) GetHmacStrike() *HMACStrike { + if m != nil { + return m.HmacStrike } return nil } +// Reply is the server's reply to the client. type Reply struct { Status *Reply_Status `protobuf:"varint,1,opt,name=status,enum=protos.Reply_Status,def=0" json:"status,omitempty"` AccountCreated *AccountCreated `protobuf:"bytes,2,opt,name=account_created" json:"account_created,omitempty"` @@ -235,264 +270,302 @@ type Reply struct { XXX_unrecognized []byte `json:"-"` } -func (this *Reply) Reset() { *this = Reply{} } -func (this *Reply) String() string { return proto.CompactTextString(this) } -func (*Reply) ProtoMessage() {} +func (m *Reply) Reset() { *m = Reply{} } +func (m *Reply) String() string { return proto.CompactTextString(m) } +func (*Reply) ProtoMessage() {} const Default_Reply_Status Reply_Status = Reply_OK -func (this *Reply) GetStatus() Reply_Status { - if this != nil && this.Status != nil { - return *this.Status +func (m *Reply) GetStatus() Reply_Status { + if m != nil && m.Status != nil { + return *m.Status } return Default_Reply_Status } -func (this *Reply) GetAccountCreated() *AccountCreated { - if this != nil { - return this.AccountCreated +func (m *Reply) GetAccountCreated() *AccountCreated { + if m != nil { + return m.AccountCreated } return nil } -func (this *Reply) GetFetched() *Fetched { - if this != nil { - return this.Fetched +func (m *Reply) GetFetched() *Fetched { + if m != nil { + return m.Fetched } return nil } -func (this *Reply) GetAnnounce() *ServerAnnounce { - if this != nil { - return this.Announce +func (m *Reply) GetAnnounce() *ServerAnnounce { + if m != nil { + return m.Announce } return nil } -func (this *Reply) GetUpload() *UploadReply { - if this != nil { - return this.Upload +func (m *Reply) GetUpload() *UploadReply { + if m != nil { + return m.Upload } return nil } -func (this *Reply) GetDownload() *DownloadReply { - if this != nil { - return this.Download +func (m *Reply) GetDownload() *DownloadReply { + if m != nil { + return m.Download } return nil } -func (this *Reply) GetRevocation() *SignedRevocation { - if this != nil { - return this.Revocation +func (m *Reply) GetRevocation() *SignedRevocation { + if m != nil { + return m.Revocation } return nil } -func (this *Reply) GetExtraRevocations() []*SignedRevocation { - if this != nil { - return this.ExtraRevocations +func (m *Reply) GetExtraRevocations() []*SignedRevocation { + if m != nil { + return m.ExtraRevocations } return nil } +// NewAccount is a request that the client may send to the server to request a +// new account. The public identity of the connecting client will be the `name' +// of the new account. type NewAccount struct { - Generation *uint32 `protobuf:"fixed32,1,req,name=generation" json:"generation,omitempty"` - Group []byte `protobuf:"bytes,2,req,name=group" json:"group,omitempty"` - HmacKey []byte `protobuf:"bytes,3,opt,name=hmac_key" json:"hmac_key,omitempty"` - XXX_unrecognized []byte `json:"-"` + // generation contains the revocation generation for the account. The + // client should pick it at random in order to hide the number of + // revocations that the client has performed. + Generation *uint32 `protobuf:"fixed32,1,req,name=generation" json:"generation,omitempty"` + // group contains the serialised bbssig.Group for authenticating + // deliveries to this account. + Group []byte `protobuf:"bytes,2,req,name=group" json:"group,omitempty"` + // hmac_key contains an HMAC key used to authenticate delivery + // attempts. + HmacKey []byte `protobuf:"bytes,3,opt,name=hmac_key" json:"hmac_key,omitempty"` + XXX_unrecognized []byte `json:"-"` } -func (this *NewAccount) Reset() { *this = NewAccount{} } -func (this *NewAccount) String() string { return proto.CompactTextString(this) } -func (*NewAccount) ProtoMessage() {} +func (m *NewAccount) Reset() { *m = NewAccount{} } +func (m *NewAccount) String() string { return proto.CompactTextString(m) } +func (*NewAccount) ProtoMessage() {} -func (this *NewAccount) GetGeneration() uint32 { - if this != nil && this.Generation != nil { - return *this.Generation +func (m *NewAccount) GetGeneration() uint32 { + if m != nil && m.Generation != nil { + return *m.Generation } return 0 } -func (this *NewAccount) GetGroup() []byte { - if this != nil { - return this.Group +func (m *NewAccount) GetGroup() []byte { + if m != nil { + return m.Group } return nil } -func (this *NewAccount) GetHmacKey() []byte { - if this != nil { - return this.HmacKey +func (m *NewAccount) GetHmacKey() []byte { + if m != nil { + return m.HmacKey } return nil } +// AccountDetails contains the state of an account. type AccountDetails struct { - Queue *uint32 `protobuf:"varint,1,req,name=queue" json:"queue,omitempty"` + // queue is the number of messages waiting at the server. + Queue *uint32 `protobuf:"varint,1,req,name=queue" json:"queue,omitempty"` + // max_queue is the maximum number of messages that the server will + // queue for this account. MaxQueue *uint32 `protobuf:"varint,2,req,name=max_queue" json:"max_queue,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (this *AccountDetails) Reset() { *this = AccountDetails{} } -func (this *AccountDetails) String() string { return proto.CompactTextString(this) } -func (*AccountDetails) ProtoMessage() {} +func (m *AccountDetails) Reset() { *m = AccountDetails{} } +func (m *AccountDetails) String() string { return proto.CompactTextString(m) } +func (*AccountDetails) ProtoMessage() {} -func (this *AccountDetails) GetQueue() uint32 { - if this != nil && this.Queue != nil { - return *this.Queue +func (m *AccountDetails) GetQueue() uint32 { + if m != nil && m.Queue != nil { + return *m.Queue } return 0 } -func (this *AccountDetails) GetMaxQueue() uint32 { - if this != nil && this.MaxQueue != nil { - return *this.MaxQueue +func (m *AccountDetails) GetMaxQueue() uint32 { + if m != nil && m.MaxQueue != nil { + return *m.MaxQueue } return 0 } +// AccountCreated is the reply to a NewAccount request. type AccountCreated struct { Details *AccountDetails `protobuf:"bytes,1,req,name=details" json:"details,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (this *AccountCreated) Reset() { *this = AccountCreated{} } -func (this *AccountCreated) String() string { return proto.CompactTextString(this) } -func (*AccountCreated) ProtoMessage() {} +func (m *AccountCreated) Reset() { *m = AccountCreated{} } +func (m *AccountCreated) String() string { return proto.CompactTextString(m) } +func (*AccountCreated) ProtoMessage() {} -func (this *AccountCreated) GetDetails() *AccountDetails { - if this != nil { - return this.Details +func (m *AccountCreated) GetDetails() *AccountDetails { + if m != nil { + return m.Details } return nil } +// Delivery is a request from a client to deliver a message to an account on +// this server. There's no explicit reply protobuf for this request. Success is +// indicated via |status|. type Delivery struct { - To []byte `protobuf:"bytes,1,req,name=to" json:"to,omitempty"` - GroupSignature []byte `protobuf:"bytes,2,opt,name=group_signature" json:"group_signature,omitempty"` - Generation *uint32 `protobuf:"fixed32,3,opt,name=generation" json:"generation,omitempty"` - Message []byte `protobuf:"bytes,4,req,name=message" json:"message,omitempty"` - OneTimePublicKey []byte `protobuf:"bytes,5,opt,name=one_time_public_key" json:"one_time_public_key,omitempty"` - HmacOfPublicKey *uint64 `protobuf:"fixed64,6,opt,name=hmac_of_public_key" json:"hmac_of_public_key,omitempty"` - OneTimeSignature []byte `protobuf:"bytes,7,opt,name=one_time_signature" json:"one_time_signature,omitempty"` - XXX_unrecognized []byte `json:"-"` + // The 32-byte, public identity of the target account. + To []byte `protobuf:"bytes,1,req,name=to" json:"to,omitempty"` + // A group signature of |message| proving authorisation to deliver + // messages to the account. + GroupSignature []byte `protobuf:"bytes,2,opt,name=group_signature" json:"group_signature,omitempty"` + // The current generation number in order for the server to send + // revocation updates. + Generation *uint32 `protobuf:"fixed32,3,opt,name=generation" json:"generation,omitempty"` + // The padded message to deliver. + Message []byte `protobuf:"bytes,4,req,name=message" json:"message,omitempty"` + // one_time_public_key contains an Ed25519 public key that was issued + // by the recipient in order to authenticate delivery attempts. + OneTimePublicKey []byte `protobuf:"bytes,5,opt,name=one_time_public_key" json:"one_time_public_key,omitempty"` + // hmac_of_public_key contains a 63-bit HMAC of public key using the + // HMAC key known to server and recipient. + HmacOfPublicKey *uint64 `protobuf:"fixed64,6,opt,name=hmac_of_public_key" json:"hmac_of_public_key,omitempty"` + // one_time_signature contains a signature, by public_key, of message. + OneTimeSignature []byte `protobuf:"bytes,7,opt,name=one_time_signature" json:"one_time_signature,omitempty"` + XXX_unrecognized []byte `json:"-"` } -func (this *Delivery) Reset() { *this = Delivery{} } -func (this *Delivery) String() string { return proto.CompactTextString(this) } -func (*Delivery) ProtoMessage() {} +func (m *Delivery) Reset() { *m = Delivery{} } +func (m *Delivery) String() string { return proto.CompactTextString(m) } +func (*Delivery) ProtoMessage() {} -func (this *Delivery) GetTo() []byte { - if this != nil { - return this.To +func (m *Delivery) GetTo() []byte { + if m != nil { + return m.To } return nil } -func (this *Delivery) GetGroupSignature() []byte { - if this != nil { - return this.GroupSignature +func (m *Delivery) GetGroupSignature() []byte { + if m != nil { + return m.GroupSignature } return nil } -func (this *Delivery) GetGeneration() uint32 { - if this != nil && this.Generation != nil { - return *this.Generation +func (m *Delivery) GetGeneration() uint32 { + if m != nil && m.Generation != nil { + return *m.Generation } return 0 } -func (this *Delivery) GetMessage() []byte { - if this != nil { - return this.Message +func (m *Delivery) GetMessage() []byte { + if m != nil { + return m.Message } return nil } -func (this *Delivery) GetOneTimePublicKey() []byte { - if this != nil { - return this.OneTimePublicKey +func (m *Delivery) GetOneTimePublicKey() []byte { + if m != nil { + return m.OneTimePublicKey } return nil } -func (this *Delivery) GetHmacOfPublicKey() uint64 { - if this != nil && this.HmacOfPublicKey != nil { - return *this.HmacOfPublicKey +func (m *Delivery) GetHmacOfPublicKey() uint64 { + if m != nil && m.HmacOfPublicKey != nil { + return *m.HmacOfPublicKey } return 0 } -func (this *Delivery) GetOneTimeSignature() []byte { - if this != nil { - return this.OneTimeSignature +func (m *Delivery) GetOneTimeSignature() []byte { + if m != nil { + return m.OneTimeSignature } return nil } +// Fetch is a request to fetch a message. It may result in either a Fetched, or +// ServerAnnounce message. (Or none at all if no messages are pending.) type Fetch struct { XXX_unrecognized []byte `json:"-"` } -func (this *Fetch) Reset() { *this = Fetch{} } -func (this *Fetch) String() string { return proto.CompactTextString(this) } -func (*Fetch) ProtoMessage() {} +func (m *Fetch) Reset() { *m = Fetch{} } +func (m *Fetch) String() string { return proto.CompactTextString(m) } +func (*Fetch) ProtoMessage() {} +// Fetched is the reply to a Fetch request if the server has a message for +// delivery. type Fetched struct { - GroupSignature []byte `protobuf:"bytes,1,req,name=group_signature" json:"group_signature,omitempty"` + // group_signature is the group signature presented by the sender. + GroupSignature []byte `protobuf:"bytes,1,req,name=group_signature" json:"group_signature,omitempty"` + // generation is the generation number used for delivery. Generation *uint32 `protobuf:"fixed32,2,req,name=generation" json:"generation,omitempty"` Message []byte `protobuf:"bytes,3,req,name=message" json:"message,omitempty"` Details *AccountDetails `protobuf:"bytes,4,req,name=details" json:"details,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (this *Fetched) Reset() { *this = Fetched{} } -func (this *Fetched) String() string { return proto.CompactTextString(this) } -func (*Fetched) ProtoMessage() {} +func (m *Fetched) Reset() { *m = Fetched{} } +func (m *Fetched) String() string { return proto.CompactTextString(m) } +func (*Fetched) ProtoMessage() {} -func (this *Fetched) GetGroupSignature() []byte { - if this != nil { - return this.GroupSignature +func (m *Fetched) GetGroupSignature() []byte { + if m != nil { + return m.GroupSignature } return nil } -func (this *Fetched) GetGeneration() uint32 { - if this != nil && this.Generation != nil { - return *this.Generation +func (m *Fetched) GetGeneration() uint32 { + if m != nil && m.Generation != nil { + return *m.Generation } return 0 } -func (this *Fetched) GetMessage() []byte { - if this != nil { - return this.Message +func (m *Fetched) GetMessage() []byte { + if m != nil { + return m.Message } return nil } -func (this *Fetched) GetDetails() *AccountDetails { - if this != nil { - return this.Details +func (m *Fetched) GetDetails() *AccountDetails { + if m != nil { + return m.Details } return nil } +// ServerAnnounce is a special type of reply to a Fetch request. The message +// comes from the server, rather than from another client and it's intended to +// be used for announcements from the server operator to all or some users. type ServerAnnounce struct { Message *Message `protobuf:"bytes,1,req,name=message" json:"message,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (this *ServerAnnounce) Reset() { *this = ServerAnnounce{} } -func (this *ServerAnnounce) String() string { return proto.CompactTextString(this) } -func (*ServerAnnounce) ProtoMessage() {} +func (m *ServerAnnounce) Reset() { *m = ServerAnnounce{} } +func (m *ServerAnnounce) String() string { return proto.CompactTextString(m) } +func (*ServerAnnounce) ProtoMessage() {} -func (this *ServerAnnounce) GetMessage() *Message { - if this != nil { - return this.Message +func (m *ServerAnnounce) GetMessage() *Message { + if m != nil { + return m.Message } return nil } @@ -503,20 +576,20 @@ type Upload struct { XXX_unrecognized []byte `json:"-"` } -func (this *Upload) Reset() { *this = Upload{} } -func (this *Upload) String() string { return proto.CompactTextString(this) } -func (*Upload) ProtoMessage() {} +func (m *Upload) Reset() { *m = Upload{} } +func (m *Upload) String() string { return proto.CompactTextString(m) } +func (*Upload) ProtoMessage() {} -func (this *Upload) GetId() uint64 { - if this != nil && this.Id != nil { - return *this.Id +func (m *Upload) GetId() uint64 { + if m != nil && m.Id != nil { + return *m.Id } return 0 } -func (this *Upload) GetSize() int64 { - if this != nil && this.Size != nil { - return *this.Size +func (m *Upload) GetSize() int64 { + if m != nil && m.Size != nil { + return *m.Size } return 0 } @@ -526,13 +599,13 @@ type UploadReply struct { XXX_unrecognized []byte `json:"-"` } -func (this *UploadReply) Reset() { *this = UploadReply{} } -func (this *UploadReply) String() string { return proto.CompactTextString(this) } -func (*UploadReply) ProtoMessage() {} +func (m *UploadReply) Reset() { *m = UploadReply{} } +func (m *UploadReply) String() string { return proto.CompactTextString(m) } +func (*UploadReply) ProtoMessage() {} -func (this *UploadReply) GetResume() int64 { - if this != nil && this.Resume != nil { - return *this.Resume +func (m *UploadReply) GetResume() int64 { + if m != nil && m.Resume != nil { + return *m.Resume } return 0 } @@ -544,27 +617,27 @@ type Download struct { XXX_unrecognized []byte `json:"-"` } -func (this *Download) Reset() { *this = Download{} } -func (this *Download) String() string { return proto.CompactTextString(this) } -func (*Download) ProtoMessage() {} +func (m *Download) Reset() { *m = Download{} } +func (m *Download) String() string { return proto.CompactTextString(m) } +func (*Download) ProtoMessage() {} -func (this *Download) GetFrom() []byte { - if this != nil { - return this.From +func (m *Download) GetFrom() []byte { + if m != nil { + return m.From } return nil } -func (this *Download) GetId() uint64 { - if this != nil && this.Id != nil { - return *this.Id +func (m *Download) GetId() uint64 { + if m != nil && m.Id != nil { + return *m.Id } return 0 } -func (this *Download) GetResume() int64 { - if this != nil && this.Resume != nil { - return *this.Resume +func (m *Download) GetResume() int64 { + if m != nil && m.Resume != nil { + return *m.Resume } return 0 } @@ -574,37 +647,40 @@ type DownloadReply struct { XXX_unrecognized []byte `json:"-"` } -func (this *DownloadReply) Reset() { *this = DownloadReply{} } -func (this *DownloadReply) String() string { return proto.CompactTextString(this) } -func (*DownloadReply) ProtoMessage() {} +func (m *DownloadReply) Reset() { *m = DownloadReply{} } +func (m *DownloadReply) String() string { return proto.CompactTextString(m) } +func (*DownloadReply) ProtoMessage() {} -func (this *DownloadReply) GetSize() int64 { - if this != nil && this.Size != nil { - return *this.Size +func (m *DownloadReply) GetSize() int64 { + if m != nil && m.Size != nil { + return *m.Size } return 0 } +// SignedRevocation is a request for the server to store an update to the group +// public key that revokes some sender. The server will reply with a revocation +// for generation x when a delivery to that generation is requested. type SignedRevocation struct { Revocation *SignedRevocation_Revocation `protobuf:"bytes,1,req,name=revocation" json:"revocation,omitempty"` Signature []byte `protobuf:"bytes,2,req,name=signature" json:"signature,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (this *SignedRevocation) Reset() { *this = SignedRevocation{} } -func (this *SignedRevocation) String() string { return proto.CompactTextString(this) } -func (*SignedRevocation) ProtoMessage() {} +func (m *SignedRevocation) Reset() { *m = SignedRevocation{} } +func (m *SignedRevocation) String() string { return proto.CompactTextString(m) } +func (*SignedRevocation) ProtoMessage() {} -func (this *SignedRevocation) GetRevocation() *SignedRevocation_Revocation { - if this != nil { - return this.Revocation +func (m *SignedRevocation) GetRevocation() *SignedRevocation_Revocation { + if m != nil { + return m.Revocation } return nil } -func (this *SignedRevocation) GetSignature() []byte { - if this != nil { - return this.Signature +func (m *SignedRevocation) GetSignature() []byte { + if m != nil { + return m.Signature } return nil } @@ -615,236 +691,282 @@ type SignedRevocation_Revocation struct { XXX_unrecognized []byte `json:"-"` } -func (this *SignedRevocation_Revocation) Reset() { *this = SignedRevocation_Revocation{} } -func (this *SignedRevocation_Revocation) String() string { return proto.CompactTextString(this) } -func (*SignedRevocation_Revocation) ProtoMessage() {} +func (m *SignedRevocation_Revocation) Reset() { *m = SignedRevocation_Revocation{} } +func (m *SignedRevocation_Revocation) String() string { return proto.CompactTextString(m) } +func (*SignedRevocation_Revocation) ProtoMessage() {} -func (this *SignedRevocation_Revocation) GetGeneration() uint32 { - if this != nil && this.Generation != nil { - return *this.Generation +func (m *SignedRevocation_Revocation) GetGeneration() uint32 { + if m != nil && m.Generation != nil { + return *m.Generation } return 0 } -func (this *SignedRevocation_Revocation) GetRevocation() []byte { - if this != nil { - return this.Revocation +func (m *SignedRevocation_Revocation) GetRevocation() []byte { + if m != nil { + return m.Revocation } return nil } +// HMACSetup can be sent by a client to establish an HMAC key if it didn't do +// so at account creation time. type HMACSetup struct { HmacKey []byte `protobuf:"bytes,1,req,name=hmac_key" json:"hmac_key,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (this *HMACSetup) Reset() { *this = HMACSetup{} } -func (this *HMACSetup) String() string { return proto.CompactTextString(this) } -func (*HMACSetup) ProtoMessage() {} +func (m *HMACSetup) Reset() { *m = HMACSetup{} } +func (m *HMACSetup) String() string { return proto.CompactTextString(m) } +func (*HMACSetup) ProtoMessage() {} -func (this *HMACSetup) GetHmacKey() []byte { - if this != nil { - return this.HmacKey +func (m *HMACSetup) GetHmacKey() []byte { + if m != nil { + return m.HmacKey } return nil } +// HMACStrike is used by a client to record a number of HMAC values as used. type HMACStrike struct { + // hmacs contains a number of 63-bit HMACs. The MSB is used to signal + // whether the HMAC should be considered used (0) or revoked (1). Hmacs []uint64 `protobuf:"fixed64,1,rep,packed,name=hmacs" json:"hmacs,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (this *HMACStrike) Reset() { *this = HMACStrike{} } -func (this *HMACStrike) String() string { return proto.CompactTextString(this) } -func (*HMACStrike) ProtoMessage() {} +func (m *HMACStrike) Reset() { *m = HMACStrike{} } +func (m *HMACStrike) String() string { return proto.CompactTextString(m) } +func (*HMACStrike) ProtoMessage() {} -func (this *HMACStrike) GetHmacs() []uint64 { - if this != nil { - return this.Hmacs +func (m *HMACStrike) GetHmacs() []uint64 { + if m != nil { + return m.Hmacs } return nil } +// KeyExchange is a message sent between clients to establish a relation. It's +// always found inside a SignedKeyExchange. type KeyExchange struct { - PublicKey []byte `protobuf:"bytes,1,req,name=public_key" json:"public_key,omitempty"` - IdentityPublic []byte `protobuf:"bytes,2,req,name=identity_public" json:"identity_public,omitempty"` - Server *string `protobuf:"bytes,3,req,name=server" json:"server,omitempty"` - Dh []byte `protobuf:"bytes,4,req,name=dh" json:"dh,omitempty"` - Dh1 []byte `protobuf:"bytes,8,opt,name=dh1" json:"dh1,omitempty"` - Group []byte `protobuf:"bytes,5,req,name=group" json:"group,omitempty"` - GroupKey []byte `protobuf:"bytes,6,req,name=group_key" json:"group_key,omitempty"` - Generation *uint32 `protobuf:"varint,7,req,name=generation" json:"generation,omitempty"` - XXX_unrecognized []byte `json:"-"` + // Ed25519 public key. + PublicKey []byte `protobuf:"bytes,1,req,name=public_key" json:"public_key,omitempty"` + // Curve25519 public key. (Used to tell the server which account to + // deliver a message to.) + // Note: in the most up-to-date revision of the Pond ratchet, this + // should be equal to |public_key|, modulo isomorphism. + IdentityPublic []byte `protobuf:"bytes,2,req,name=identity_public" json:"identity_public,omitempty"` + // The URL of this user's home server. + Server *string `protobuf:"bytes,3,req,name=server" json:"server,omitempty"` + // A Curve25519, initial Diffie-Hellman value. + Dh []byte `protobuf:"bytes,4,req,name=dh" json:"dh,omitempty"` + // dh1 contains the second, curve25519, public key if the new-form + // ratchet is being used. + Dh1 []byte `protobuf:"bytes,8,opt,name=dh1" json:"dh1,omitempty"` + // A serialised bbssig.Group. + Group []byte `protobuf:"bytes,5,req,name=group" json:"group,omitempty"` + // A bbssig.PrivateKey to authorise message delivery. + GroupKey []byte `protobuf:"bytes,6,req,name=group_key" json:"group_key,omitempty"` + // The generation number of |group|. + Generation *uint32 `protobuf:"varint,7,req,name=generation" json:"generation,omitempty"` + // Protocol version number. Absence means V1. + SupportedVersion *int32 `protobuf:"varint,9,opt,name=supported_version" json:"supported_version,omitempty"` + XXX_unrecognized []byte `json:"-"` } -func (this *KeyExchange) Reset() { *this = KeyExchange{} } -func (this *KeyExchange) String() string { return proto.CompactTextString(this) } -func (*KeyExchange) ProtoMessage() {} +func (m *KeyExchange) Reset() { *m = KeyExchange{} } +func (m *KeyExchange) String() string { return proto.CompactTextString(m) } +func (*KeyExchange) ProtoMessage() {} -func (this *KeyExchange) GetPublicKey() []byte { - if this != nil { - return this.PublicKey +func (m *KeyExchange) GetPublicKey() []byte { + if m != nil { + return m.PublicKey } return nil } -func (this *KeyExchange) GetIdentityPublic() []byte { - if this != nil { - return this.IdentityPublic +func (m *KeyExchange) GetIdentityPublic() []byte { + if m != nil { + return m.IdentityPublic } return nil } -func (this *KeyExchange) GetServer() string { - if this != nil && this.Server != nil { - return *this.Server +func (m *KeyExchange) GetServer() string { + if m != nil && m.Server != nil { + return *m.Server } return "" } -func (this *KeyExchange) GetDh() []byte { - if this != nil { - return this.Dh +func (m *KeyExchange) GetDh() []byte { + if m != nil { + return m.Dh } return nil } -func (this *KeyExchange) GetDh1() []byte { - if this != nil { - return this.Dh1 +func (m *KeyExchange) GetDh1() []byte { + if m != nil { + return m.Dh1 } return nil } -func (this *KeyExchange) GetGroup() []byte { - if this != nil { - return this.Group +func (m *KeyExchange) GetGroup() []byte { + if m != nil { + return m.Group } return nil } -func (this *KeyExchange) GetGroupKey() []byte { - if this != nil { - return this.GroupKey +func (m *KeyExchange) GetGroupKey() []byte { + if m != nil { + return m.GroupKey } return nil } -func (this *KeyExchange) GetGeneration() uint32 { - if this != nil && this.Generation != nil { - return *this.Generation +func (m *KeyExchange) GetGeneration() uint32 { + if m != nil && m.Generation != nil { + return *m.Generation } return 0 } +func (m *KeyExchange) GetSupportedVersion() int32 { + if m != nil && m.SupportedVersion != nil { + return *m.SupportedVersion + } + return 0 +} + +// A SignedKeyExchange is a message that's sent between clients and exposed in +// the UI. It's typically found in a PEM block with type "POND KEY EXCHANGE". type SignedKeyExchange struct { - Signed []byte `protobuf:"bytes,1,req,name=signed" json:"signed,omitempty"` + // signed contains a serialised KeyExchange message. + Signed []byte `protobuf:"bytes,1,req,name=signed" json:"signed,omitempty"` + // signature contains an Ed25519 signature of |signed| by + // |signed.public_key|. Signature []byte `protobuf:"bytes,2,req,name=signature" json:"signature,omitempty"` XXX_unrecognized []byte `json:"-"` } -func (this *SignedKeyExchange) Reset() { *this = SignedKeyExchange{} } -func (this *SignedKeyExchange) String() string { return proto.CompactTextString(this) } -func (*SignedKeyExchange) ProtoMessage() {} +func (m *SignedKeyExchange) Reset() { *m = SignedKeyExchange{} } +func (m *SignedKeyExchange) String() string { return proto.CompactTextString(m) } +func (*SignedKeyExchange) ProtoMessage() {} -func (this *SignedKeyExchange) GetSigned() []byte { - if this != nil { - return this.Signed +func (m *SignedKeyExchange) GetSigned() []byte { + if m != nil { + return m.Signed } return nil } -func (this *SignedKeyExchange) GetSignature() []byte { - if this != nil { - return this.Signature +func (m *SignedKeyExchange) GetSignature() []byte { + if m != nil { + return m.Signature } return nil } +// Message is typically contained within a NaCl box that's passed between +// clients using Delivery and Fetch. type Message struct { - Id *uint64 `protobuf:"fixed64,1,req,name=id" json:"id,omitempty"` - Time *int64 `protobuf:"varint,2,req,name=time" json:"time,omitempty"` - Body []byte `protobuf:"bytes,3,req,name=body" json:"body,omitempty"` - BodyEncoding *Message_Encoding `protobuf:"varint,4,opt,name=body_encoding,enum=protos.Message_Encoding" json:"body_encoding,omitempty"` - MyNextDh []byte `protobuf:"bytes,5,opt,name=my_next_dh" json:"my_next_dh,omitempty"` - InReplyTo *uint64 `protobuf:"varint,6,opt,name=in_reply_to" json:"in_reply_to,omitempty"` - AlsoAck []uint64 `protobuf:"varint,10,rep,name=also_ack" json:"also_ack,omitempty"` - Files []*Message_Attachment `protobuf:"bytes,7,rep,name=files" json:"files,omitempty"` - DetachedFiles []*Message_Detachment `protobuf:"bytes,8,rep,name=detached_files" json:"detached_files,omitempty"` - SupportedVersion *int32 `protobuf:"varint,9,opt,name=supported_version" json:"supported_version,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (this *Message) Reset() { *this = Message{} } -func (this *Message) String() string { return proto.CompactTextString(this) } -func (*Message) ProtoMessage() {} - -func (this *Message) GetId() uint64 { - if this != nil && this.Id != nil { - return *this.Id + // id is generated by the sender in order for the receiver to associate + // replies. + Id *uint64 `protobuf:"fixed64,1,req,name=id" json:"id,omitempty"` + // time is the creation time of the message in epoch nanoseconds. + Time *int64 `protobuf:"varint,2,req,name=time" json:"time,omitempty"` + // body, after decoding, is a utf8 message. + Body []byte `protobuf:"bytes,3,req,name=body" json:"body,omitempty"` + BodyEncoding *Message_Encoding `protobuf:"varint,4,opt,name=body_encoding,enum=protos.Message_Encoding" json:"body_encoding,omitempty"` + // my_next_dh contains a Curve25519 public value for future messages. + MyNextDh []byte `protobuf:"bytes,5,opt,name=my_next_dh" json:"my_next_dh,omitempty"` + // in_reply_to, if set, contains the |id| value of a previous message + // sent by the recipient. + InReplyTo *uint64 `protobuf:"varint,6,opt,name=in_reply_to" json:"in_reply_to,omitempty"` + // also_ack contains message ids for other messages that are also + // acknowledged by this message. + AlsoAck []uint64 `protobuf:"varint,10,rep,name=also_ack" json:"also_ack,omitempty"` + Files []*Message_Attachment `protobuf:"bytes,7,rep,name=files" json:"files,omitempty"` + DetachedFiles []*Message_Detachment `protobuf:"bytes,8,rep,name=detached_files" json:"detached_files,omitempty"` + // supported_version allows a client to advertise the maximum supported + // version that it speaks. + SupportedVersion *int32 `protobuf:"varint,9,opt,name=supported_version" json:"supported_version,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} + +func (m *Message) GetId() uint64 { + if m != nil && m.Id != nil { + return *m.Id } return 0 } -func (this *Message) GetTime() int64 { - if this != nil && this.Time != nil { - return *this.Time +func (m *Message) GetTime() int64 { + if m != nil && m.Time != nil { + return *m.Time } return 0 } -func (this *Message) GetBody() []byte { - if this != nil { - return this.Body +func (m *Message) GetBody() []byte { + if m != nil { + return m.Body } return nil } -func (this *Message) GetBodyEncoding() Message_Encoding { - if this != nil && this.BodyEncoding != nil { - return *this.BodyEncoding +func (m *Message) GetBodyEncoding() Message_Encoding { + if m != nil && m.BodyEncoding != nil { + return *m.BodyEncoding } - return 0 + return Message_RAW } -func (this *Message) GetMyNextDh() []byte { - if this != nil { - return this.MyNextDh +func (m *Message) GetMyNextDh() []byte { + if m != nil { + return m.MyNextDh } return nil } -func (this *Message) GetInReplyTo() uint64 { - if this != nil && this.InReplyTo != nil { - return *this.InReplyTo +func (m *Message) GetInReplyTo() uint64 { + if m != nil && m.InReplyTo != nil { + return *m.InReplyTo } return 0 } -func (this *Message) GetAlsoAck() []uint64 { - if this != nil { - return this.AlsoAck +func (m *Message) GetAlsoAck() []uint64 { + if m != nil { + return m.AlsoAck } return nil } -func (this *Message) GetFiles() []*Message_Attachment { - if this != nil { - return this.Files +func (m *Message) GetFiles() []*Message_Attachment { + if m != nil { + return m.Files } return nil } -func (this *Message) GetDetachedFiles() []*Message_Detachment { - if this != nil { - return this.DetachedFiles +func (m *Message) GetDetachedFiles() []*Message_Detachment { + if m != nil { + return m.DetachedFiles } return nil } -func (this *Message) GetSupportedVersion() int32 { - if this != nil && this.SupportedVersion != nil { - return *this.SupportedVersion +func (m *Message) GetSupportedVersion() int32 { + if m != nil && m.SupportedVersion != nil { + return *m.SupportedVersion } return 0 } @@ -855,20 +977,20 @@ type Message_Attachment struct { XXX_unrecognized []byte `json:"-"` } -func (this *Message_Attachment) Reset() { *this = Message_Attachment{} } -func (this *Message_Attachment) String() string { return proto.CompactTextString(this) } -func (*Message_Attachment) ProtoMessage() {} +func (m *Message_Attachment) Reset() { *m = Message_Attachment{} } +func (m *Message_Attachment) String() string { return proto.CompactTextString(m) } +func (*Message_Attachment) ProtoMessage() {} -func (this *Message_Attachment) GetFilename() string { - if this != nil && this.Filename != nil { - return *this.Filename +func (m *Message_Attachment) GetFilename() string { + if m != nil && m.Filename != nil { + return *m.Filename } return "" } -func (this *Message_Attachment) GetContents() []byte { - if this != nil { - return this.Contents +func (m *Message_Attachment) GetContents() []byte { + if m != nil { + return m.Contents } return nil } @@ -883,48 +1005,48 @@ type Message_Detachment struct { XXX_unrecognized []byte `json:"-"` } -func (this *Message_Detachment) Reset() { *this = Message_Detachment{} } -func (this *Message_Detachment) String() string { return proto.CompactTextString(this) } -func (*Message_Detachment) ProtoMessage() {} +func (m *Message_Detachment) Reset() { *m = Message_Detachment{} } +func (m *Message_Detachment) String() string { return proto.CompactTextString(m) } +func (*Message_Detachment) ProtoMessage() {} -func (this *Message_Detachment) GetFilename() string { - if this != nil && this.Filename != nil { - return *this.Filename +func (m *Message_Detachment) GetFilename() string { + if m != nil && m.Filename != nil { + return *m.Filename } return "" } -func (this *Message_Detachment) GetSize() uint64 { - if this != nil && this.Size != nil { - return *this.Size +func (m *Message_Detachment) GetSize() uint64 { + if m != nil && m.Size != nil { + return *m.Size } return 0 } -func (this *Message_Detachment) GetPaddedSize() uint64 { - if this != nil && this.PaddedSize != nil { - return *this.PaddedSize +func (m *Message_Detachment) GetPaddedSize() uint64 { + if m != nil && m.PaddedSize != nil { + return *m.PaddedSize } return 0 } -func (this *Message_Detachment) GetChunkSize() uint32 { - if this != nil && this.ChunkSize != nil { - return *this.ChunkSize +func (m *Message_Detachment) GetChunkSize() uint32 { + if m != nil && m.ChunkSize != nil { + return *m.ChunkSize } return 0 } -func (this *Message_Detachment) GetKey() []byte { - if this != nil { - return this.Key +func (m *Message_Detachment) GetKey() []byte { + if m != nil { + return m.Key } return nil } -func (this *Message_Detachment) GetUrl() string { - if this != nil && this.Url != nil { - return *this.Url +func (m *Message_Detachment) GetUrl() string { + if m != nil && m.Url != nil { + return *m.Url } return "" } diff --git a/protos/pond.proto b/protos/pond.proto index 104aab3..ec3b8dc 100644 --- a/protos/pond.proto +++ b/protos/pond.proto @@ -226,6 +226,8 @@ message KeyExchange { required bytes group_key = 6; // The generation number of |group|. required uint32 generation = 7; + // Protocol version number. Absence means V1. + optional int32 supported_version = 9; } // A SignedKeyExchange is a message that's sent between clients and exposed in diff --git a/server/protos/server.pb.go b/server/protos/server.pb.go index 1faf4c9..32a18f4 100644 --- a/server/protos/server.pb.go +++ b/server/protos/server.pb.go @@ -1,48 +1,60 @@ -// Code generated by protoc-gen-go. -// source: github.com/agl/pond/server/protos/server.proto +// Code generated by protoc-gen-gogo. +// source: protos/server.proto // DO NOT EDIT! +/* +Package protos is a generated protocol buffer package. + +It is generated from these files: + protos/server.proto + +It has these top-level messages: + Config +*/ package protos -import proto "github.com/golang/protobuf/proto" -import json "encoding/json" +import proto "code.google.com/p/gogoprotobuf/proto" import math "math" -// Reference proto, json, and math imports to suppress error if they are not otherwise used. +// Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal -var _ = &json.SyntaxError{} var _ = math.Inf +// Config contains the server's configutation options. type Config struct { - Port *uint32 `protobuf:"varint,1,req,name=port" json:"port,omitempty"` - Address *string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` - AllowRegistration *bool `protobuf:"varint,3,opt,name=allow_registration,def=1" json:"allow_registration,omitempty"` - XXX_unrecognized []byte `json:"-"` + Port *uint32 `protobuf:"varint,1,req,name=port" json:"port,omitempty"` + // address is an optional IP address. If given, the server will only + // listen on this address. + Address *string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` + // allow_registration controls whether new account requests will be + // processed. + AllowRegistration *bool `protobuf:"varint,3,opt,name=allow_registration,def=1" json:"allow_registration,omitempty"` + XXX_unrecognized []byte `json:"-"` } -func (this *Config) Reset() { *this = Config{} } -func (this *Config) String() string { return proto.CompactTextString(this) } -func (*Config) ProtoMessage() {} +func (m *Config) Reset() { *m = Config{} } +func (m *Config) String() string { return proto.CompactTextString(m) } +func (*Config) ProtoMessage() {} const Default_Config_AllowRegistration bool = true -func (this *Config) GetPort() uint32 { - if this != nil && this.Port != nil { - return *this.Port +func (m *Config) GetPort() uint32 { + if m != nil && m.Port != nil { + return *m.Port } return 0 } -func (this *Config) GetAddress() string { - if this != nil && this.Address != nil { - return *this.Address +func (m *Config) GetAddress() string { + if m != nil && m.Address != nil { + return *m.Address } return "" } -func (this *Config) GetAllowRegistration() bool { - if this != nil && this.AllowRegistration != nil { - return *this.AllowRegistration +func (m *Config) GetAllowRegistration() bool { + if m != nil && m.AllowRegistration != nil { + return *m.AllowRegistration } return Default_Config_AllowRegistration } diff --git a/server/server.go b/server/server.go index eebef38..46a7de1 100644 --- a/server/server.go +++ b/server/server.go @@ -24,6 +24,8 @@ import ( "github.com/golang/protobuf/proto" ) +//go:generate protoc --proto_path=$GOPATH/src:. --gogo_out=. protos/server.proto + const ( // maxQueue is the maximum number of messages that we'll queue for any // given user.