github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/teams/loader_types.go (about) 1 package teams 2 3 import ( 4 "crypto/sha256" 5 "fmt" 6 7 "github.com/keybase/client/go/libkb" 8 "github.com/keybase/client/go/protocol/keybase1" 9 ) 10 11 // -------------------------------------------------- 12 13 // An operation that occurs simultaneously on the child and parent team chains. 14 // This struct holds the child half of the operation. 15 type parentChildOperation struct { 16 // The seqno in the parent sigchain that corresponds to this operation. 17 parentSeqno keybase1.Seqno 18 // The type of the child link 19 linkType libkb.SigchainV2Type 20 // The new subteam name. The only PCOs at the mo' are subteam renames. 21 newName keybase1.TeamName 22 } 23 24 // -------------------------------------------------- 25 26 type SignerX struct { 27 signer keybase1.UserVersion 28 // Whether the user is definitely an implicit admin 29 implicitAdmin bool 30 } 31 32 func NewSignerX(signer keybase1.UserVersion, implicitAdmin bool) SignerX { 33 return SignerX{signer, implicitAdmin} 34 } 35 36 // -------------------------------------------------- 37 38 type ChainLinkUnpacked struct { 39 source *SCChainLink 40 outerLink *libkb.OuterLinkV2WithMetadata 41 // inner is nil if the link is stubbed 42 inner *SCChainLinkPayload 43 // nil if the link is stubbed 44 innerLinkID libkb.LinkID 45 // nil if the link is stubbed 46 innerTeamID keybase1.TeamID 47 } 48 49 func UnpackChainLink(link *SCChainLink) (*ChainLinkUnpacked, error) { 50 return unpackChainLink(link) 51 } 52 53 func unpackChainLink(link *SCChainLink) (*ChainLinkUnpacked, error) { 54 var outerLink *libkb.OuterLinkV2WithMetadata 55 var err error 56 switch { 57 case link.Sig != "": 58 outerLink, err = libkb.DecodeOuterLinkV2(link.Sig) 59 case link.SigV2Payload != "": 60 outerLink, err = libkb.DecodeStubbedOuterLinkV2(link.SigV2Payload) 61 default: 62 return nil, fmt.Errorf("cannot decode chain link, no sig v2 payload") 63 } 64 if err != nil { 65 return nil, fmt.Errorf("unpack outer: %v", err) 66 } 67 err = outerLink.AssertSomeFields(link.Version, link.Seqno) 68 if err != nil { 69 return nil, err 70 } 71 var inner *SCChainLinkPayload 72 var innerLinkID libkb.LinkID 73 var innerTeamID keybase1.TeamID 74 if link.Payload == "" { 75 // stubbed inner link 76 } else { 77 payload, err := link.UnmarshalPayload() 78 if err != nil { 79 return nil, fmt.Errorf("unmarshaling link payload: %v", err) 80 } 81 inner = &payload 82 tmp := sha256.Sum256([]byte(link.Payload)) 83 innerLinkID = libkb.LinkID(tmp[:]) 84 innerTeamID, err = inner.TeamID() 85 if err != nil { 86 return nil, err 87 } 88 } 89 ret := &ChainLinkUnpacked{ 90 source: link, 91 outerLink: outerLink, 92 inner: inner, 93 innerLinkID: innerLinkID, 94 innerTeamID: innerTeamID, 95 } 96 return ret, nil 97 } 98 99 func (l *ChainLinkUnpacked) Seqno() keybase1.Seqno { return l.outerLink.Seqno } 100 101 func (l *ChainLinkUnpacked) SeqType() keybase1.SeqType { return l.outerLink.SeqType } 102 103 func (l *ChainLinkUnpacked) Prev() libkb.LinkID { return l.outerLink.Prev } 104 105 func (l *ChainLinkUnpacked) LinkID() libkb.LinkID { return l.outerLink.LinkID() } 106 107 func (l *ChainLinkUnpacked) SigID() keybase1.SigID { return l.outerLink.SigID() } 108 109 func (l *ChainLinkUnpacked) LinkType() libkb.SigchainV2Type { return l.outerLink.LinkType } 110 111 func (l *ChainLinkUnpacked) isStubbed() bool { return l.inner == nil } 112 113 func (l ChainLinkUnpacked) SignatureMetadata() keybase1.SignatureMetadata { 114 return l.inner.SignatureMetadata() 115 } 116 117 func (l ChainLinkUnpacked) SigChainLocation() keybase1.SigChainLocation { 118 return l.inner.SigChainLocation() 119 } 120 121 func (l ChainLinkUnpacked) LinkTriple() keybase1.LinkTriple { 122 return keybase1.LinkTriple{ 123 Seqno: l.Seqno(), 124 SeqType: l.SeqType(), 125 LinkID: l.LinkID().Export(), 126 } 127 } 128 129 func (l ChainLinkUnpacked) TeamAdmin() *SCTeamAdmin { return l.inner.TeamAdmin() } 130 131 func (i *SCChainLinkPayload) SignatureMetadata() keybase1.SignatureMetadata { 132 return keybase1.SignatureMetadata{ 133 PrevMerkleRootSigned: i.Body.MerkleRoot.ToMerkleRootV2(), 134 SigChainLocation: i.SigChainLocation(), 135 Time: keybase1.TimeFromSeconds(int64(i.Ctime)), 136 } 137 } 138 139 func (l *ChainLinkUnpacked) AssertInnerOuterMatch() (err error) { 140 if l.inner == nil { 141 return fmt.Errorf("cannot check inner-outer match without inner link") 142 } 143 144 var prev libkb.LinkID 145 if l.inner.Prev != nil { 146 prev, err = libkb.LinkIDFromHex(*l.inner.Prev) 147 if err != nil { 148 return err 149 } 150 } 151 152 linkType, err := libkb.SigchainV2TypeFromV1TypeTeams(l.inner.Body.Type) 153 if err != nil { 154 if l.outerLink.LinkType.IsSupportedTeamType() { 155 // Supported outer type but unrecognized inner type. 156 return err 157 } 158 if !l.outerLink.IgnoreIfUnsupported { 159 // Unsupported outer type marked as critical. 160 return NewUnsupportedLinkTypeError(l.outerLink.LinkType, l.inner.Body.Type) 161 } 162 163 // If the inner link type is not recognized, and the outer link type is not a valid 164 // team link type. Then this may be a link type from the future. 165 // Let it slide without really checking that the inner and outer types match 166 // (because this client doesn't know the mapping). 167 // By assigning this tautology, which will always pass AssertFields. 168 linkType = l.outerLink.LinkType 169 } 170 171 useSeqType := l.inner.SeqType 172 if l.outerLink.SeqType == 0 { 173 // There are links where seq_type is unset on the outer link 174 // but set on the inner link. 175 // Let these pass. 176 useSeqType = l.outerLink.SeqType 177 } 178 179 return l.outerLink.AssertFields( 180 l.inner.Body.Version, 181 l.inner.Seqno, 182 prev, 183 l.innerLinkID, 184 linkType, 185 useSeqType, 186 l.inner.IgnoreIfUnsupported, 187 nil) 188 } 189 190 func (l *ChainLinkUnpacked) PTKGeneration() (ret keybase1.PerTeamKeyGeneration) { 191 if l.isStubbed() || l.inner.Body.Team == nil || l.inner.Body.Team.PerTeamKey == nil { 192 return ret 193 } 194 return l.inner.Body.Team.PerTeamKey.Generation 195 }