Skip to content

Commit

Permalink
Merge pull request #44 from bifurcation/expose-cik
Browse files Browse the repository at this point in the history
Expose some formerly private objects methods
  • Loading branch information
suhasHere committed Mar 25, 2020
2 parents 495bb15 + 692bf58 commit 2ff3aa1
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 77 deletions.
16 changes: 16 additions & 0 deletions credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,22 @@ func (c Credential) Type() CredentialType {
}
}

func (c *Credential) SetPrivateKey(priv SignaturePrivateKey) {
c.privateKey = &priv
}

func (c *Credential) RemovePrivateKey() {
c.privateKey = nil
}

func (c Credential) PrivateKey() (SignaturePrivateKey, bool) {
if c.privateKey == nil {
return SignaturePrivateKey{}, false
}

return *c.privateKey, true
}

func (c Credential) PublicKey() *SignaturePublicKey {
switch {
// TODO(#35) case c.X509 != nil:
Expand Down
18 changes: 11 additions & 7 deletions crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,14 @@ func (cs CipherSuite) deriveAppSecret(secret []byte, label string, node nodeInde
return cs.hkdfExpandLabel(secret, label, ctx, length)
}

func (cs CipherSuite) hpke() hpkeInstance {
func (cs CipherSuite) hpke() HPKEInstance {
cc := cs.constants()
suite, err := hpke.AssembleCipherSuite(cc.HPKEKEM, cc.HPKEKDF, cc.HPKEAEAD)
if err != nil {
panic("Unable to construct HPKE ciphersuite")
}

return hpkeInstance{cs, suite}
return HPKEInstance{cs, suite}
}

///
Expand All @@ -202,12 +202,12 @@ type HPKECiphertext struct {
Ciphertext []byte `tls:"head=4"`
}

type hpkeInstance struct {
type HPKEInstance struct {
BaseSuite CipherSuite
Suite hpke.CipherSuite
}

func (h hpkeInstance) Generate() (HPKEPrivateKey, error) {
func (h HPKEInstance) Generate() (HPKEPrivateKey, error) {
priv, pub, err := h.Suite.KEM.GenerateKeyPair(rand.Reader)
if err != nil {
return HPKEPrivateKey{}, err
Expand All @@ -220,7 +220,7 @@ func (h hpkeInstance) Generate() (HPKEPrivateKey, error) {
return key, nil
}

func (h hpkeInstance) Derive(seed []byte) (HPKEPrivateKey, error) {
func (h HPKEInstance) Derive(seed []byte) (HPKEPrivateKey, error) {
digest := h.BaseSuite.digest(seed)

var priv hpke.KEMPrivateKey
Expand All @@ -244,7 +244,7 @@ func (h hpkeInstance) Derive(seed []byte) (HPKEPrivateKey, error) {
return key, nil
}

func (h hpkeInstance) Encrypt(pub HPKEPublicKey, aad, pt []byte) (HPKECiphertext, error) {
func (h HPKEInstance) Encrypt(pub HPKEPublicKey, aad, pt []byte) (HPKECiphertext, error) {
pkR, err := h.Suite.KEM.Unmarshal(pub.Data)
if err != nil {
return HPKECiphertext{}, err
Expand All @@ -259,7 +259,7 @@ func (h hpkeInstance) Encrypt(pub HPKEPublicKey, aad, pt []byte) (HPKECiphertext
return HPKECiphertext{enc, ct}, nil
}

func (h hpkeInstance) Decrypt(priv HPKEPrivateKey, aad []byte, ct HPKECiphertext) ([]byte, error) {
func (h HPKEInstance) Decrypt(priv HPKEPrivateKey, aad []byte, ct HPKECiphertext) ([]byte, error) {
skR, err := h.Suite.KEM.UnmarshalPrivate(priv.Data)
if err != nil {
return nil, err
Expand All @@ -286,6 +286,10 @@ type SignaturePublicKey struct {
Data []byte `tls:"head=2"`
}

func (pub SignaturePublicKey) Equals(other SignaturePublicKey) bool {
return bytes.Equal(pub.Data, other.Data)
}

type SignatureScheme uint16

const (
Expand Down
17 changes: 11 additions & 6 deletions messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type ClientInitKey struct {
privateKey *HPKEPrivateKey `tls:"omit"`
}

func (cik ClientInitKey) GetPrivateKey() (HPKEPrivateKey, bool) {
func (cik ClientInitKey) PrivateKey() (HPKEPrivateKey, bool) {
if cik.privateKey == nil {
return HPKEPrivateKey{}, false
}
Expand All @@ -53,6 +53,10 @@ func (cik *ClientInitKey) SetPrivateKey(priv HPKEPrivateKey) {
cik.InitKey = priv.PublicKey
}

func (cik *ClientInitKey) RemovePrivateKey() {
cik.privateKey = nil
}

func (cik ClientInitKey) toBeSigned() ([]byte, error) {
enc, err := syntax.Marshal(struct {
Version SupportedVersion
Expand Down Expand Up @@ -198,17 +202,16 @@ func (p *Proposal) UnmarshalTLS(data []byte) (int, error) {
return 0, fmt.Errorf("mls.proposal: Unmarshal failed for ProposalTpe")
}

var read int
switch proposalType {
case ProposalTypeAdd:
p.Add = new(AddProposal)
read, err = s.Read(p.Add)
_, err = s.Read(p.Add)
case ProposalTypeUpdate:
p.Update = new(UpdateProposal)
read, err = s.Read(p.Update)
_, err = s.Read(p.Update)
case ProposalTypeRemove:
p.Remove = new(RemoveProposal)
read, err = s.Read(p.Remove)
_, err = s.Read(p.Remove)
default:
err = fmt.Errorf("mls.proposal: ProposalType type not allowed")
}
Expand All @@ -217,7 +220,7 @@ func (p *Proposal) UnmarshalTLS(data []byte) (int, error) {
return 0, err
}

return read, nil
return s.Position(), nil
}

///
Expand Down Expand Up @@ -667,5 +670,7 @@ func (w Welcome) Decrypt(suite CipherSuite, epochSecret []byte) (*GroupInfo, err
return nil, fmt.Errorf("mls.state: invalid groupInfo")
}

gi.Tree.CipherSuite = suite

return gi, nil
}
2 changes: 1 addition & 1 deletion ratchet-tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ func (t *RatchetTree) Encap(from leafIndex, context, leafSecret []byte) (*Direct
pk := t.Nodes[rnode].Node.PublicKey
ct, err := t.CipherSuite.hpke().Encrypt(*pk, context, pathSecret)
if err != nil {
panic(fmt.Errorf("mls.rtn. Encap encrypt for resolve failed %v", err))
panic(fmt.Errorf("mls.rtn. Encap encrypt failed: %v", err))
}
pathNode.EncryptedPathSecrets = append(pathNode.EncryptedPathSecrets, ct)
}
Expand Down
44 changes: 24 additions & 20 deletions state.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package mls
import (
"bytes"
"fmt"
"github.com/bifurcation/mint/syntax"
"math/rand"
"reflect"

"github.com/bifurcation/mint/syntax"
)

///
Expand Down Expand Up @@ -51,7 +53,7 @@ type State struct {
Keys keyScheduleEpoch `tls:"omit"`
}

func newEmptyState(groupID []byte, cs CipherSuite, leafPriv HPKEPrivateKey, cred Credential) *State {
func NewEmptyState(groupID []byte, cs CipherSuite, leafPriv HPKEPrivateKey, cred Credential) *State {
tree := newRatchetTree(cs)
tree.AddLeaf(0, &leafPriv.PublicKey, &cred)
secret := make([]byte, cs.newDigest().Size())
Expand All @@ -72,13 +74,14 @@ func newEmptyState(groupID []byte, cs CipherSuite, leafPriv HPKEPrivateKey, cred
return s
}

func newStateFromWelcome(suite CipherSuite, epochSecret []byte, welcome Welcome) (*State, leafIndex, []byte, error) {
func NewStateFromWelcome(suite CipherSuite, epochSecret []byte, welcome Welcome) (*State, leafIndex, []byte, error) {
gi, err := welcome.Decrypt(suite, epochSecret)
if err != nil {
return nil, 0, nil, err
}

s := &State{
CipherSuite: suite,
Epoch: gi.Epoch,
GroupID: gi.GroupID,
Tree: *gi.Tree.clone(),
Expand All @@ -91,7 +94,7 @@ func newStateFromWelcome(suite CipherSuite, epochSecret []byte, welcome Welcome)
return s, gi.SignerIndex, gi.Confirmation, nil
}

func newJoinedState(ciks []ClientInitKey, welcome Welcome) (*State, error) {
func NewJoinedState(ciks []ClientInitKey, welcome Welcome) (*State, error) {
var kp KeyPackage
var clientInitKey ClientInitKey
var encKeyPackage EncryptedKeyPackage
Expand Down Expand Up @@ -145,7 +148,7 @@ func newJoinedState(ciks []ClientInitKey, welcome Welcome) (*State, error) {
}

// Construct a new state based on the GroupInfo
s, signerIndex, confirmation, err := newStateFromWelcome(suite, kp.EpochSecret, welcome)
s, signerIndex, confirmation, err := NewStateFromWelcome(suite, kp.EpochSecret, welcome)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -209,23 +212,23 @@ func negotiateWithPeer(groupID []byte, myCIKs, otherCIKs []ClientInitKey, commit
}

// init our state and add the negotiated peer's cik
s := newEmptyState(groupID, mySelectedCik.CipherSuite, *mySelectedCik.privateKey, mySelectedCik.Credential)
add := s.add(otherSelectedCik)
s := NewEmptyState(groupID, mySelectedCik.CipherSuite, *mySelectedCik.privateKey, mySelectedCik.Credential)
add := s.Add(otherSelectedCik)
// update tree state
_, err := s.handle(add)
_, err := s.Handle(add)
if err != nil {
return nil, nil, err
}
// commit the add and generate welcome to be sent to the peer
_, welcome, newState, err := s.commit(commitSecret)
_, welcome, newState, err := s.Commit(commitSecret)
if err != nil {
panic(fmt.Errorf("mls.state: commit failure"))
}

return welcome, newState, nil
}

func (s State) add(cik ClientInitKey) *MLSPlaintext {
func (s State) Add(cik ClientInitKey) *MLSPlaintext {
addProposal := Proposal{
Add: &AddProposal{
ClientInitKey: cik,
Expand All @@ -234,7 +237,7 @@ func (s State) add(cik ClientInitKey) *MLSPlaintext {
return s.sign(addProposal)
}

func (s State) update(leafSecret []byte) *MLSPlaintext {
func (s State) Update(leafSecret []byte) *MLSPlaintext {
key, err := s.CipherSuite.hpke().Derive(leafSecret)
if err != nil {
panic(fmt.Errorf("mls.state: deriving secret for update failure %v", err))
Expand All @@ -252,7 +255,7 @@ func (s State) update(leafSecret []byte) *MLSPlaintext {
return pt
}

func (s *State) remove(removed leafIndex) *MLSPlaintext {
func (s *State) Remove(removed leafIndex) *MLSPlaintext {
removeProposal := Proposal{
Remove: &RemoveProposal{
Removed: removed,
Expand All @@ -261,7 +264,7 @@ func (s *State) remove(removed leafIndex) *MLSPlaintext {
return s.sign(removeProposal)
}

func (s *State) commit(leafSecret []byte) (*MLSPlaintext, *Welcome, *State, error) {
func (s *State) Commit(leafSecret []byte) (*MLSPlaintext, *Welcome, *State, error) {
commit := Commit{}
var joiners []ClientInitKey

Expand Down Expand Up @@ -544,7 +547,7 @@ func (s *State) ratchetAndSign(op Commit, updateSecret []byte, prevGrpCtx GroupC
return pt, nil
}

func (s *State) handle(pt *MLSPlaintext) (*State, error) {
func (s *State) Handle(pt *MLSPlaintext) (*State, error) {
if !bytes.Equal(pt.GroupID, s.GroupID) {
return nil, fmt.Errorf("mls.state: groupId mismatch")
}
Expand Down Expand Up @@ -786,7 +789,7 @@ func (s *State) decrypt(ct *MLSCiphertext) (*MLSPlaintext, error) {
return pt, nil
}

func (s *State) protect(data []byte) (*MLSCiphertext, error) {
func (s *State) Protect(data []byte) (*MLSCiphertext, error) {
pt := &MLSPlaintext{
GroupID: s.GroupID,
Epoch: s.Epoch,
Expand All @@ -802,7 +805,7 @@ func (s *State) protect(data []byte) (*MLSCiphertext, error) {
return s.encrypt(pt)
}

func (s *State) unprotect(ct *MLSCiphertext) ([]byte, error) {
func (s *State) Unprotect(ct *MLSCiphertext) ([]byte, error) {
pt, err := s.decrypt(ct)
if err != nil {
return nil, err
Expand Down Expand Up @@ -888,16 +891,17 @@ func (s State) clone() *State {
return clone
}

// Compare the public aspects of two nodes
// Compare the public and shared private aspects of two nodes
func (s State) Equals(o State) bool {
suite := s.CipherSuite == o.CipherSuite
groupID := bytes.Equal(s.GroupID, o.GroupID)
epoch := s.Epoch == o.Epoch
tree := s.Tree.Equals(&o.Tree)
cth := bytes.Equal(s.ConfirmedTranscriptHash, o.ConfirmedTranscriptHash)
ith := bytes.Equal(s.InterimTranscriptHash, o.InterimTranscriptHash)
keys := reflect.DeepEqual(s.Keys, o.Keys)

return suite && groupID && epoch && tree && cth && ith
return suite && groupID && epoch && tree && cth && ith && keys
}

// Isolated getters and setters for public and secret state
Expand All @@ -920,11 +924,11 @@ type StateSecrets struct {
Tree TreeSecrets
}

func newStateFromWelcomeAndSecrets(welcome Welcome, ss StateSecrets) (*State, error) {
func NewStateFromWelcomeAndSecrets(welcome Welcome, ss StateSecrets) (*State, error) {
// Import the base data using some information from the secrets
suite := ss.CipherSuite
epochSecret := ss.Keys.EpochSecret
s, _, confirmation, err := newStateFromWelcome(suite, epochSecret, welcome)
s, _, confirmation, err := NewStateFromWelcome(suite, epochSecret, welcome)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 2ff3aa1

Please sign in to comment.