github.com/holochain/holochain-proto@v0.1.0-alpha-26.0.20200915073418-5c83169c9b5b/revocation.go (about) 1 // Copyright (C) 2013-2017, The MetaCurrency Project (Eric Harris-Braun, Arthur Brock, et. al.) 2 // Use of this source code is governed by GPLv3 found in the LICENSE file 3 //---------------------------------------------------------------------------------------- 4 5 // interface for revoking keys 6 7 package holochain 8 9 import ( 10 "encoding/json" 11 "errors" 12 ic "github.com/libp2p/go-libp2p-crypto" 13 ) 14 15 type Revocation interface { 16 Verify() error 17 Marshal() (string, error) 18 Unmarshal(string) error 19 } 20 21 var SelfRevocationDoesNotVerify = errors.New("self revocation does not verify") 22 23 // SelfRevocation holds the old key being revoked and the new key, other revocation data and 24 // the two cryptographic signatures of that data by the two keys to confirm the revocation 25 type SelfRevocation struct { 26 Data []byte // concatination of key length, two marshaled keys, and revocation properties 27 OldSig []byte // signature of oldnew by old key 28 NewSig []byte // signature by oldnew new key 29 } 30 31 func NewSelfRevocation(old, new ic.PrivKey, payload []byte) (rP *SelfRevocation, err error) { 32 oldPub := old.GetPublic() 33 newPub := new.GetPublic() 34 var oldPubBytes, newPubBytes, oldSig, newSig []byte 35 oldPubBytes, err = ic.MarshalPublicKey(oldPub) 36 if err != nil { 37 return 38 } 39 newPubBytes, _ = ic.MarshalPublicKey(newPub) 40 if err != nil { 41 return 42 } 43 data := []byte{byte(len(oldPubBytes))} 44 45 data = append(data, oldPubBytes...) 46 data = append(data, newPubBytes...) 47 data = append(data, payload...) 48 49 oldSig, err = old.Sign(data) 50 newSig, err = new.Sign(data) 51 52 revocation := SelfRevocation{ 53 Data: data, 54 OldSig: oldSig, 55 NewSig: newSig, 56 } 57 rP = &revocation 58 return 59 } 60 61 func (r *SelfRevocation) getOldKey() (key ic.PubKey, err error) { 62 l := int(r.Data[0]) 63 bytes := r.Data[1 : l+1] 64 key, err = ic.UnmarshalPublicKey(bytes) 65 return 66 67 } 68 69 func (r *SelfRevocation) getNewKey() (key ic.PubKey, err error) { 70 l := int(r.Data[0]) 71 bytes := r.Data[l+1 : l*2+1] 72 key, err = ic.UnmarshalPublicKey(bytes) 73 return 74 } 75 76 func (r *SelfRevocation) Marshal() (data string, err error) { 77 var j []byte 78 j, err = json.Marshal(r) 79 if err == nil { 80 data = string(j) 81 } 82 return 83 } 84 85 func (r *SelfRevocation) Unmarshal(data string) (err error) { 86 err = json.Unmarshal([]byte(data), r) 87 return 88 } 89 90 // Verify confirms that a self-revocation is properly signed 91 func (r *SelfRevocation) Verify() (err error) { 92 var oldPubKey, newPubKey ic.PubKey 93 oldPubKey, err = r.getOldKey() 94 if err != nil { 95 return 96 } 97 var matches bool 98 matches, err = oldPubKey.Verify(r.Data, r.OldSig) 99 if err != nil { 100 return err 101 } 102 if !matches { 103 return SelfRevocationDoesNotVerify 104 } 105 newPubKey, err = r.getNewKey() 106 107 if err != nil { 108 return 109 } 110 matches, err = newPubKey.Verify(r.Data, r.NewSig) 111 if err != nil { 112 return err 113 } 114 if !matches { 115 return SelfRevocationDoesNotVerify 116 } 117 return 118 }