github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/chain_link_parse_2.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package libkb 5 6 import ( 7 "crypto/sha256" 8 "encoding/base64" 9 "fmt" 10 "strconv" 11 12 "github.com/buger/jsonparser" 13 "github.com/keybase/client/go/jsonparserw" 14 "github.com/keybase/client/go/kbcrypto" 15 "github.com/keybase/client/go/msgpack" 16 "github.com/keybase/client/go/sigid" 17 pkgerrors "github.com/pkg/errors" 18 19 keybase1 "github.com/keybase/client/go/protocol/keybase1" 20 ) 21 22 // badWhitespaceLinkIDConversion converts what we get by naively computing 23 // the LinkID to what it should be (on the basis of a mistakenly stripped newline). 24 var badWhitespaceLinkIDConversion = map[keybase1.LinkID]keybase1.LinkID{ 25 "c6403b7eec2f2ada4f5e0349bd59488c6fc6a8ff62f7e4a9b559f3e672690f23": "03fb1e2c0e61e3715c41515045d89d2f788dbcc7eb671b94ac12ee5f805bbe70", 26 "67f63579dcb143cde80af2196037e61b8d5410677939c3635fbf44e34e106d6e": "09527db7672bf23a9681ac86c70826cdc01ed1e467252a76ca4bf4ad0964efd7", 27 "0adfc5a682a1f717469ce5781f03110ea47aad62a65fba5c9db6c93ffd1d31ef": "12c9203c98fe0b1c80a551f8933b2c870fcc3754a8ea05591e43a4d528fadc68", 28 "b068f86b9a6b12b45c4a727e2b2506900d84107a66331dadc50e9127eec1df11": "14ef90159164e19228ff21c909b764e239f27f0fff49f86414a2dde9b719845f", 29 "179ba2604ca94bd3c049fd37bc60fdf7b6f5aa331ec5432b6ce8fb5e30a76c80": "18688c45cbe05ee2b72567acc696b3856f9876dff0ec3ea927ad7632a3f48fe6", 30 "781db37c7eec976551e0c5d06a1fc64c84c06c601c093f71661892776335a360": "2c11a140d8f231af6d69543474138a503191486ae6b5739892c5e0c6c0c4c348", 31 "5f6f398fed407020498d5258183ac5cf09b96832a57c19b412b4a5a186a8ddae": "2cf8b9ffa500089b6db873acbabdba771e8e897c0a899a01f8967a7280cfd0da", 32 "2ea16dd1ed2339cc193e8e4d36f3b12955276b9bd02d00c0ccac19a865fedb8a": "2efe839231d6b03f85ab3c542e870e7062329a8c5e384f1289b00be7c7afb8ab", 33 "fc6febd300f012a8796bc29b7f9f119736fbece786b5bf41535debb4c4065e18": "32f5dd2643eabf3828f7f03ccded07d8d8a29e352df6130c3a4232104398d819", 34 "908df90fcdc82b13689c3826fec2b113d0f5ea95ab12dfccac0c8017e051523a": "33a61f19c0ca52257214f97524ef10441cf85215ff171868f53561dfd7b14c81", 35 "f025714a5b92f29ece12c5d3dfa3f1cff430d00375381ce3d3029f57cb6fbe87": "36328ab1cf15cc3dd2ba4c771ca1066b2d44714780ad8e83894611e2a2642003", 36 "3f59f95a6027faad6cd7d0ecdd087824cad743af8c460b24d8c3dd3e73fdc564": "371f9ae63d56ec853fa53941e79d29abbb4cd11aa926715d354d18d687b0ca71", 37 "8629ef8148542ba40ab650de522a08f7fcba12e1c4dd9cae702054ddd1db3469": "374f1da46fd8238ab9f288183cb78f3c6a59732f4b19705763c9d6ac356015ef", 38 "a05c5533c3a0be260c2c61d3e026c7f0ed9f050cf7fb1b3375561e9b74900f39": "3803be27ec0c61b3fdcd8b9b7c78de3df73766736ef00727267858d34a039c7d", 39 "ca574ddc1f5b1d8cfcea4c98cbf9318aa7730654fc27f155194a0331743018f2": "3ca5ef6a6115a8a86d7d94cb3565f43f05f7975d66015455dd6cc32b73936177", 40 "c342332cd2e16bef3fcd3c179b4c68e1711966a42d2f761a8cad1d9018b6e50c": "3cdd165df44ba7f8331b89213f213dab36482ef513d023c5d2b0f6bfd11d5678", 41 "2c7d63521953099c4dd1eeaecaf73ea7141358d861804581afabdb41fbc4c6dd": "43f21601ffaeae70eca2f585949f42c67e85e93cf2a6847d6c20ffd81a9ff890", 42 "608a930cd23b8326c6c54c333a3b06c5a7817e6dd0776931600d0232c9b64415": "4948115615d7dceb90bcdd818f69b66b5899339a2b747b5e6dc0f6987abbcbd0", 43 "5b01b5f4868b1a57c17dfd7e0a29e814c2ebf517124d3fc9e80de91a14f36853": "4c3f7855eb307aa5620962e15de84b2cfe3f728a9722c43906b12e0f3082cb87", 44 "e155732239cdfbc7e8f984724048ea55837f1dc2e296103f3b8b5b920e1d06a0": "5957f583bec18cc6f381355843c21f903fe47d584a9816e072f3f102f1f488be", 45 "19fb5089a2c976a3da70313509853967ddc9e7aca66bbd83b692ec6c25f42ad0": "605525686fef18180be692df6106c13dae39abb2799dc9e8bed1e2bb64e9b886", 46 "9cc3b515ef372c4dab04f634ae781eab44dc3c905b2e50eeb491cde73e6abc76": "616d9710b3a594ab00292d3d414e6e141929935a133bfa9a25ec4a155a403e5c", 47 "35567057358f9a9907f8ac53195c32a9c8297c244420f77f34973ea9aa0c99bf": "61e9f4b437fccac8abd396acfc96b17558c9c355b57f4a5f2f3698e78f19532f", 48 "992232ad3e598cad26dc8247a59ae00026c710aad8d4d0aa30c8b22c30c41068": "6f3d73ddf575f2033a48268a564575e40edbb5111cc057984f51f463d4e8ed58", 49 "2b999c0c8a6d7580fe15cad0718555d1ad4dbe7ee66fbdf064e50314e63908b0": "720b80b7c15cb9a3d21a2eec228bceb5db6f0ef54df2d0aef08aec5ed1632257", 50 "070a137418bf79584da4806d342cb85da195b81ba34ab17866301e0074a62106": "740f9140a7901defaaaec10042722b30d2fee457337b7ae8e9de3b9fc05d109f", 51 "9fe6d8d33743b1c115386f6e0640b1a1a20b78f5abd33068a122eee76b0ac1fa": "7560f896c19457365225f48be0217b8a00519f1daccefee4c097dd1b4594dd66", 52 "0a66d169b9735d3d6017bebb3c6663651d0e7945b7807da7fc0f81cd89a1bab4": "7772c99774570202a2c5ac017eefc8296f613e64c8d4adff4ba7991b553431f5", 53 "c76aed537f11f43d9f29960e64ac3826d8b588db523ecdc5d3962f370a603e91": "7d97355e5917c5bcc14ba3a1994398b3fa36416768b663c1454069de84a4fca2", 54 "f34d8e9cb975c2ff1695a62f6382705a9c8495d418fdf31b8e07ea8838726fbc": "893567013c77f45755279bf1138fecbb54cd3a55bf5814504cf0406acbe4bfeb", 55 "7a5c2c7535131175c8881f7d22425f9ceb7ac2a9c9a1bd4a1f3002f257130fbc": "8d7c1a0c99186f972afc5d3624aca2f88ddc3a5dbf84e826ef0b520c31a78aa3", 56 "9567542c190ccece597d9fd75a376406dde0c0a66dfece93bd458b7b8209001c": "94fde9d49c29cba59c949b35dd424de3a0daccf8a04ba443833e3328d495b9d8", 57 "6b4439bb3b4296fc3121e7254138da0112ee1f5d19060424a3795a52ba0118e1": "9644d4db6a4928ad1075a22b4473d1efa47c99a1a2a779450d4cd67d9115b9ba", 58 "49fdec5413bb7a31d12afd6d6d51449d51b0e294322b652dd5826d22b2240688": "9db59496652a1587ed56ec6ae15917b6d0ef4ac9a14dda97bfa4d2427a80e2b8", 59 "ccfa667ad9a1a392b51c719fcb5d526eee06e74e541d17e008b34ad8c0f2b2a6": "9f8c0a29a6ba3a521db2cd4d3e2ae15223dbcd5d5d1201e33ebb2dee1b61342f", 60 "1403ea660224a2ec5cd87c96f675cbb5d44535962c4b77c78e9711096579feec": "a9efa00bc479cb40ac0521749520f5a7a38a4ba4e698ee03355a85a8464b3840", 61 "c8890433c797440189f7dd99c8830d3524f4ed89cc5493380cbca463ef2f53bf": "ac3ecaa2aa1d638867026f0c54a1d895777f366d02bfef37403275aa0d4f8322", 62 "02e298aae0a3cefb14b53b9aa3c2757ddfd07f2b2bd70aca5d0fa1b23dd63818": "acf150b2d57a3aa65574bc2bb97e224413ce3f5344fd24fc7c3282da48cc2f3d", 63 "4b9d7cb38779b31acff69bb2426bbe7a3a5718e0b51f6197acf06f84fea30d67": "b23dfd34e58a814543e1f8368b9d07922abec213afca6d2b76722825794acffa", 64 "1cf025e248cca9ecd59936bb2c6a35f3842ca9a96bb264d2a53606476629266f": "b74b420f49b771ec04e656101f86c9729cf328b0fd32f5082d04d3c39f8ccea7", 65 "9c30bbd352353746885c0d0455c9482852f4cc824367a188d71650348847d1ad": "b9f188d0c6638e3bef3dfc3476c04078bb2aef2a9249cc77b6f009692967388a", 66 "3be37854d6b2585cab0b4371df454372b919fe688fb12bee28ccbce7c0de6375": "d380d18672da3c18f0804baf6b28f5efda76d64220a152c000f2b3f9af8b6603", 67 "9fb504227c9df7f10fe887c67038a4a9cd694a2b28ab8f5f47c23a86dce26a45": "d7ae76e4fdae7034b07e515d5684adcd51afea5a22b8520d2c61d31f5028fc6e", 68 "f74cf3b94f3896fa8a6413749072085c86544c4a51dd551128b39f57b0b43e63": "da99975f9ae8cdeb9e3a42a1166617dbf6afbcf841919dcf05145a73a7026cc2", 69 "e570d6a661985326582524f4b5d177fb2027847863cdc8d2c4a073c71f420e2d": "e449b1cd1d6f2a86a0f800c47e7d1ad26bbb6c76b983bd78154972c51f77e960", 70 "01932d6b39ab9a7ee0ca835ef4301adba0a2cd6da63fb07696153166d48fc075": "f1509495f4f1d46e43dcdd341156b975f7ad19aefeb250a80fd2b236c517a891", 71 "99668480e4731a47a81051e35d4957780395990d718d8629a8653ba718d489f2": "f5f324e91a94c073fdc936b50d56250133dc19415ae592d2c7cb99db9e980e1b", 72 } 73 74 func fixupSeqType(st *keybase1.SeqType) { 75 if *st == keybase1.SeqType_NONE { 76 *st = keybase1.SeqType_PUBLIC 77 } 78 } 79 80 func importLinkFromServerV2Stubbed(m MetaContext, parent *SigChain, raw string) (ret *ChainLink, err error) { 81 ol, err := DecodeStubbedOuterLinkV2(raw) 82 if err != nil { 83 return nil, err 84 } 85 86 fixupSeqType(&ol.SeqType) 87 88 if !ol.IgnoreIfUnsupported.Bool() && !ol.LinkType.IsSupportedType() { 89 return nil, ChainLinkStubbedUnsupportedError{fmt.Sprintf("Stubbed link with type %d is unknown and not marked with IgnoreIfUnsupported", ol.LinkType)} 90 } 91 92 linkID := ol.LinkID() 93 94 // Because the outer link does not have a highSkip parent object, we check 95 // for the nullity of highSkipSeqno to see if highSkip should be set, since 96 // a null highSkipHash is valid when specifying highSkip=0. 97 var highSkipPtr *HighSkip 98 if ol.HighSkipSeqno != nil { 99 highSkip := NewHighSkip(*ol.HighSkipSeqno, *ol.HighSkipHash) 100 highSkipPtr = &highSkip 101 } 102 103 unpacked := &ChainLinkUnpacked{ 104 prev: ol.Prev, 105 seqno: ol.Seqno, 106 seqType: ol.SeqType, 107 ignoreIfUnsupported: ol.IgnoreIfUnsupported, 108 highSkip: highSkipPtr, 109 sigVersion: ol.Version, 110 outerLinkV2: ol, 111 stubbed: true, 112 } 113 ret = NewChainLink(m.G(), parent, linkID) 114 ret.unpacked = unpacked 115 return ret, nil 116 } 117 118 type importRes struct { 119 kid keybase1.KID 120 linkID LinkID 121 sigID keybase1.SigID 122 sig string 123 payload []byte 124 ol2 *OuterLinkV2WithMetadata 125 } 126 127 func getPGPSig(m MetaContext, data []byte) (sig string) { 128 sig = jsonGetString(data, "sig") 129 if sig == "" || !IsPGPSig(sig) { 130 return "" 131 } 132 return sig 133 } 134 135 func jsonGetString(d []byte, args ...string) string { 136 s, err := jsonparserw.GetString(d, args...) 137 if err != nil { 138 return "" 139 } 140 return s 141 142 } 143 144 func importServerTrustFields(m MetaContext, tmp *ChainLinkUnpacked, data []byte, selfUID keybase1.UID) error { 145 if selfUID.Equal(tmp.uid) { 146 tmp.proofText = jsonGetString(data, "proof_text_full") 147 } 148 149 if i, err := jsonparserw.GetInt(data, "merkle_seqno"); err == nil { 150 tmp.firstAppearedMerkleSeqnoUnverified = keybase1.Seqno(i) 151 } 152 return nil 153 } 154 155 func ImportLinkFromServer(m MetaContext, parent *SigChain, data []byte, selfUID keybase1.UID) (ret *ChainLink, err error) { 156 157 sig2Stubbed := jsonGetString(data, "s2") 158 if sig2Stubbed != "" { 159 return importLinkFromServerV2Stubbed(m, parent, sig2Stubbed) 160 } 161 162 versionRaw, err := jsonparserw.GetInt(data, "sig_version") 163 if err != nil || versionRaw == 0 { 164 return nil, ChainLinkError{"cannot read signature version from server"} 165 } 166 167 pgpSig := getPGPSig(m, data) 168 sigVersion := SigVersion(versionRaw) 169 170 var ir *importRes 171 switch { 172 case sigVersion == KeybaseSignatureV1 && pgpSig != "": 173 ir, err = importLinkFromServerPGP(m, pgpSig, data) 174 case sigVersion == KeybaseSignatureV1 && pgpSig == "": 175 ir, err = importLinkFromServerV1NaCl(m, data) 176 case sigVersion == KeybaseSignatureV2 && pgpSig == "": 177 ir, err = importLinkFromServerV2Unstubbed(m, data) 178 default: 179 err = ChainLinkError{fmt.Sprintf("bad link back from server; version=%d; pgp=%v", sigVersion, (pgpSig != ""))} 180 } 181 if err != nil { 182 return nil, err 183 } 184 185 ret = NewChainLink(m.G(), parent, ir.linkID) 186 tmp := ChainLinkUnpacked{sigVersion: sigVersion} 187 tmp.outerLinkV2 = ir.ol2 188 189 err = tmp.unpackPayloadJSON(m.G(), ir.payload, ret.id) 190 if err != nil { 191 m.Debug("unpack payload json err: %s", err) 192 return nil, err 193 } 194 err = tmp.assertPayloadSigVersionMatchesHint(ir.payload) 195 if err != nil { 196 return nil, err 197 } 198 199 tmp.sig = ir.sig 200 tmp.sigID = ir.sigID 201 // this might overwrite the actions of unpackPayloadJSON. TODO: to change 202 // unpackPayloadJSON to fix this issue. 203 tmp.kid = ir.kid 204 205 err = importServerTrustFields(m, &tmp, data, selfUID) 206 if err != nil { 207 return nil, err 208 } 209 210 ret.unpacked = &tmp 211 ret.hashVerified = true 212 ret.payloadVerified = true 213 214 return ret, nil 215 } 216 217 func computeLinkIDFromHashWithWhitespaceFixes(m MetaContext, payload []byte) (LinkID, error) { 218 hsh := sha256.Sum256(payload) 219 linkID := LinkID(hsh[:]) 220 converted, found := badWhitespaceLinkIDConversion[linkID.Export()] 221 if !found { 222 return linkID, nil 223 } 224 last := len(payload) - 1 225 if payload[last] != '\n' { 226 err := ChainLinkError{fmt.Sprintf("failed to strip newline from line '%s'", linkID.Export())} 227 return nil, err 228 } 229 m.Debug("Fixing payload hash by stripping newline on link '%s'", linkID.Export()) 230 toHash := payload[0:last] 231 hsh = sha256.Sum256(toHash) 232 fixedLinkID := LinkID(hsh[:]) 233 if !fixedLinkID.Export().Eq(converted) { 234 err := ChainLinkError{fmt.Sprintf("failed hash comparison after whitespace-fixing link '%s'", linkID.Export())} 235 return nil, err 236 } 237 return fixedLinkID, nil 238 } 239 240 func (s *sigChainPayloadJSON) KID() (ret keybase1.KID, err error) { 241 tmp, err := jsonparserw.GetString(s.b, "body", "key", "kid") 242 if err != nil { 243 return ret, err 244 } 245 ret = keybase1.KIDFromString(tmp) 246 return ret, nil 247 } 248 249 func (s *sigChainPayloadJSON) Seqno() (keybase1.Seqno, error) { 250 seqno, err := jsonparserw.GetInt(s.b, "seqno") 251 return keybase1.Seqno(seqno), err 252 } 253 254 func (s *sigChainPayloadJSON) Type() (string, error) { 255 return jsonparserw.GetString(s.b, "body", "type") 256 } 257 258 func (s *sigChainPayloadJSON) Version() (SigVersion, error) { 259 tmp, err := jsonparserw.GetInt(s.b, "body", "version") 260 return SigVersion(tmp), err 261 } 262 263 func (s *sigChainPayloadJSON) ClientNameAndVersion() (string, string) { 264 name, _ := jsonparserw.GetString(s.b, "client", "name") 265 version, _ := jsonparserw.GetString(s.b, "client", "version") 266 return name, version 267 } 268 269 func (s *sigChainPayloadJSON) AssertJSON(linkID LinkID) (err error) { 270 if !isJSONObject(s.b, linkID) { 271 return ChainLinkError{"JSON payload has leading garbage"} 272 } 273 return nil 274 } 275 276 func (s *sigChainPayloadJSON) Prev() (LinkID, error) { 277 data, typ, _, err := jsonparserw.Get(s.b, "prev") 278 if err != nil { 279 return nil, err 280 } 281 if typ == jsonparser.Null { 282 return nil, nil 283 } 284 if typ != jsonparser.String { 285 return nil, ChainLinkError{"bad JSON type for prev"} 286 } 287 tmp := string(data) 288 return LinkIDFromHex(tmp) 289 } 290 291 func (s *sigChainPayloadJSON) HasRevocations() bool { 292 if _, _, _, err := jsonparserw.Get(s.b, "body", "revoke", "sig_id"); err == nil { 293 return true 294 } 295 if _, _, _, err := jsonparserw.Get(s.b, "body", "revoke", "sig_ids", "[0]"); err == nil { 296 return true 297 } 298 if _, _, _, err := jsonparserw.Get(s.b, "body", "revoke", "kid"); err == nil { 299 return true 300 } 301 if _, _, _, err := jsonparserw.Get(s.b, "body", "revoke", "kids", "[0]"); err == nil { 302 return true 303 } 304 return false 305 } 306 307 func (s *sigChainPayloadJSON) HighSkip() (*HighSkip, error) { 308 hs, dataType, _, err := jsonparserw.Get(s.b, "high_skip") 309 // high_skip is optional, but must be an object if it exists 310 if err != nil { 311 switch pkgerrors.Cause(err) { 312 case jsonparser.KeyPathNotFoundError: 313 return nil, nil 314 default: 315 return nil, err 316 } 317 } 318 319 if dataType != jsonparser.Object { 320 return nil, ChainLinkError{fmt.Sprintf("When provided, expected high_skip to be a JSON object, was %v.", dataType)} 321 } 322 323 highSkipSeqnoInt, err := jsonparserw.GetInt(hs, "seqno") 324 if err != nil { 325 return nil, err 326 } 327 328 // highSkipHash can either be null (zero-value of a LinkID) or a hexstring. 329 // We call GetString first instead of Get so we only parse the value 330 // twice for the first link. 331 highSkipHashStr, err := jsonparserw.GetString(hs, "hash") 332 var highSkipHash LinkID 333 if err != nil { 334 // If there was an error parsing as a string, make sure the value is null. 335 _, dataType, _, getErr := jsonparserw.Get(hs, "hash") 336 if getErr != nil { 337 return nil, getErr 338 } 339 if dataType != jsonparser.Null { 340 return nil, ChainLinkError{ 341 fmt.Sprintf("high_skip.hash was neither a valid string (%v) nor null.", err.Error()), 342 } 343 } 344 } else { 345 highSkipHash, err = LinkIDFromHex(highSkipHashStr) 346 if err != nil { 347 return nil, err 348 } 349 } 350 351 highSkip := NewHighSkip(keybase1.Seqno(highSkipSeqnoInt), highSkipHash) 352 return &highSkip, nil 353 } 354 355 func (s *sigChainPayloadJSON) toSigIDSuffixParameters() (ret keybase1.SigIDSuffixParameters, err error) { 356 var typ string 357 var vers SigVersion 358 typ, err = s.Type() 359 if err != nil { 360 return ret, err 361 } 362 vers, err = s.Version() 363 if err != nil { 364 return ret, err 365 } 366 return keybase1.SigIDSuffixParametersFromTypeAndVersion(typ, keybase1.SigVersion(vers)), nil 367 } 368 369 func newSigInfo(kid keybase1.KID, payload []byte, sig kbcrypto.NaclSignature) *kbcrypto.NaclSigInfo { 370 return &kbcrypto.NaclSigInfo{ 371 Kid: kid.ToBinaryKID(), 372 Payload: payload, 373 Sig: sig, 374 SigType: kbcrypto.SigKbEddsa, 375 HashType: kbcrypto.HashPGPSha512, 376 Detached: true, 377 } 378 } 379 380 func decodeSig1Imploded(s string) (*kbcrypto.NaclSignature, error) { 381 raw, err := base64.StdEncoding.DecodeString(s) 382 if err != nil { 383 return nil, err 384 } 385 var ret kbcrypto.NaclSignature 386 copy(ret[:], raw) 387 return &ret, nil 388 } 389 390 func importLinkFromServerV1NaCl(m MetaContext, packed []byte) (*importRes, error) { 391 var sigBody []byte 392 var ret importRes 393 var sigIDBase keybase1.SigIDBase 394 var params keybase1.SigIDSuffixParameters 395 396 sig1ImplodedRaw := jsonGetString(packed, "si1") 397 if sig1ImplodedRaw == "" { 398 return nil, ChainLinkError{"no si1 field as expected"} 399 } 400 401 sig1Imploded, err := decodeSig1Imploded(sig1ImplodedRaw) 402 if err != nil { 403 return nil, err 404 } 405 406 payloadJSON, err := getPayloadJSONFromServerLink(packed) 407 if err != nil { 408 return nil, err 409 } 410 version, err := payloadJSON.Version() 411 if err != nil { 412 return nil, err 413 } 414 if version != KeybaseSignatureV1 { 415 return nil, ChainLinkError{"inner chainlink showed wrong version, while expecting 1"} 416 } 417 ret.linkID = payloadJSON.Hash() 418 err = payloadJSON.AssertJSON(ret.linkID) 419 if err != nil { 420 return nil, err 421 } 422 ret.kid, err = payloadJSON.KID() 423 if err != nil { 424 return nil, err 425 } 426 sigInfo := newSigInfo(ret.kid, payloadJSON.Bytes(), *sig1Imploded) 427 clientName, clientVersion := payloadJSON.ClientNameAndVersion() 428 sigBody, sigIDBase, err = sigid.ComputeSigBodyAndID(sigInfo, clientName, clientVersion) 429 if err != nil { 430 return nil, err 431 } 432 params, err = payloadJSON.toSigIDSuffixParameters() 433 if err != nil { 434 return nil, err 435 } 436 ret.sigID = sigIDBase.ToSigID(params) 437 ret.sig = base64.StdEncoding.EncodeToString(sigBody) 438 ret.payload = payloadJSON.Bytes() 439 return &ret, nil 440 } 441 442 type sig2Imploded struct { 443 _struct bool `codec:",toarray"` //nolint 444 Sig kbcrypto.NaclSignature 445 OuterLink OuterLinkV2 446 NumFields int 447 } 448 449 type sigChainPayloadJSON struct { 450 b []byte 451 } 452 453 func newSigChainPayloadJSON(s string) *sigChainPayloadJSON { 454 return &sigChainPayloadJSON{b: []byte(s)} 455 } 456 457 func newSigChainPayloadJSONFromBytes(b []byte) *sigChainPayloadJSON { 458 return &sigChainPayloadJSON{b: b} 459 } 460 461 func (s *sigChainPayloadJSON) Bytes() []byte { 462 return s.b 463 } 464 465 func (s *sigChainPayloadJSON) Hash() LinkID { 466 return ComputeLinkID(s.b) 467 } 468 469 func getPayloadJSONFromServerLink(packed []byte) (*sigChainPayloadJSON, error) { 470 data, _, _, err := jsonparserw.Get(packed, "payload_json") 471 if err != nil { 472 return nil, err 473 } 474 sdata, err := strconv.Unquote(`"` + string(data) + `"`) 475 if err != nil { 476 return nil, err 477 } 478 return newSigChainPayloadJSON(sdata), nil 479 } 480 481 func decodeSig2Imploded(s string) (*sig2Imploded, error) { 482 raw, err := base64.StdEncoding.DecodeString(s) 483 if err != nil { 484 return nil, err 485 } 486 var ret sig2Imploded 487 if !msgpack.IsEncodedMsgpackArray(raw) { 488 return nil, ChainLinkError{"expected a msgpack array but got leading junk"} 489 } 490 err = msgpack.Decode(&ret, raw) 491 if err != nil { 492 return nil, err 493 } 494 return &ret, nil 495 } 496 497 func importLinkFromServerV2Unstubbed(m MetaContext, packed []byte) (*importRes, error) { 498 var ret importRes 499 var sigIDBase keybase1.SigIDBase 500 var params keybase1.SigIDSuffixParameters 501 502 sig2ImplodedRaw := jsonGetString(packed, "si2") 503 if sig2ImplodedRaw == "" { 504 return nil, ChainLinkError{"no si2 field as expected"} 505 } 506 payloadJSON, err := getPayloadJSONFromServerLink(packed) 507 if err != nil { 508 return nil, err 509 } 510 version, err := payloadJSON.Version() 511 if err != nil { 512 return nil, err 513 } 514 if version != KeybaseSignatureV2 { 515 return nil, ChainLinkError{"inner chainlink showed wrong version, while expecting 2"} 516 } 517 innerLinkID := payloadJSON.Hash() 518 sig2Imploded, err := decodeSig2Imploded(sig2ImplodedRaw) 519 if err != nil { 520 return nil, err 521 } 522 sig2Imploded.OuterLink.Curr = innerLinkID 523 prev, err := payloadJSON.Prev() 524 if err != nil { 525 return nil, err 526 } 527 sig2Imploded.OuterLink.Prev = prev 528 seqno, err := payloadJSON.Seqno() 529 if err != nil { 530 return nil, err 531 } 532 sig2Imploded.OuterLink.Seqno = seqno 533 fixupSeqType(&sig2Imploded.OuterLink.SeqType) 534 535 outerPayload, err := sig2Imploded.OuterLink.EncodePartial(sig2Imploded.NumFields) 536 if err != nil { 537 m.Debug("EncodePartial failed on input si2=%s", sig2ImplodedRaw) 538 return nil, err 539 } 540 ret.linkID = ComputeLinkID(outerPayload) 541 542 err = payloadJSON.AssertJSON(ret.linkID) 543 if err != nil { 544 return nil, err 545 } 546 547 ret.kid, err = payloadJSON.KID() 548 if err != nil { 549 return nil, err 550 } 551 552 sigInfo := newSigInfo(ret.kid, outerPayload, sig2Imploded.Sig) 553 554 sigBody, err := kbcrypto.EncodePacketToBytes(sigInfo) 555 if err != nil { 556 return nil, err 557 } 558 ret.sig = base64.StdEncoding.EncodeToString(sigBody) 559 sigIDBase = kbcrypto.ComputeSigIDFromSigBody(sigBody) 560 params, err = payloadJSON.toSigIDSuffixParameters() 561 if err != nil { 562 return nil, err 563 } 564 ret.sigID = sigIDBase.ToSigID(params) 565 566 ret.ol2 = &OuterLinkV2WithMetadata{ 567 OuterLinkV2: sig2Imploded.OuterLink, 568 raw: outerPayload, 569 sigID: ret.sigID, 570 sig: base64.StdEncoding.EncodeToString(sigBody), 571 kid: ret.kid, 572 } 573 linkTypeStr, err := payloadJSON.Type() 574 if err != nil { 575 return nil, err 576 } 577 578 linkType, err := SigchainV2TypeFromV1TypeAndRevocations( 579 linkTypeStr, 580 SigHasRevokes(payloadJSON.HasRevocations()), 581 sig2Imploded.OuterLink.IgnoreIfUnsupported, 582 ) 583 if err != nil { 584 return nil, err 585 } 586 highSkip, err := payloadJSON.HighSkip() 587 if err != nil { 588 return nil, err 589 } 590 err = sig2Imploded.OuterLink.AssertFields( 591 KeybaseSignatureV2, 592 seqno, 593 prev, 594 innerLinkID, 595 linkType, 596 sig2Imploded.OuterLink.SeqType, 597 sig2Imploded.OuterLink.IgnoreIfUnsupported, 598 highSkip, 599 ) 600 if err != nil { 601 return nil, err 602 } 603 ret.payload = payloadJSON.Bytes() 604 return &ret, nil 605 } 606 607 func importLinkFromServerPGP(m MetaContext, sig string, packed []byte) (*importRes, error) { 608 var ret importRes 609 var err error 610 var sigIDBase keybase1.SigIDBase 611 612 ret.payload, sigIDBase, err = SigExtractPGPPayload(sig) 613 if err != nil { 614 return nil, err 615 } 616 ret.sigID = sigIDBase.ToSigIDLegacy() 617 ret.linkID, err = computeLinkIDFromHashWithWhitespaceFixes(m, ret.payload) 618 if err != nil { 619 return nil, err 620 } 621 payloadJSON := newSigChainPayloadJSONFromBytes(ret.payload) 622 623 err = payloadJSON.AssertJSON(ret.linkID) 624 if err != nil { 625 return nil, err 626 } 627 628 // Very old PGP signatures did not include kids in signature bodies. 629 // So the server always returns such KIDs, and we check for equality 630 // with what's in the payload if it was specified. 631 payloadKID, _ := payloadJSON.KID() 632 rawServerKID, err := jsonparserw.GetString(packed, "kid") 633 if err != nil { 634 return nil, err 635 } 636 serverKID := keybase1.KIDFromString(rawServerKID) 637 if serverKID.IsNil() { 638 return nil, ChainLinkError{"server returned an invalid KID for PGP key"} 639 } 640 if !payloadKID.IsNil() && !payloadKID.Equal(serverKID) { 641 return nil, ChainLinkKIDMismatchError{"server returned a bad KID that didn't match PGP body"} 642 } 643 ret.kid = serverKID 644 ret.payload = payloadJSON.Bytes() 645 ret.sig = sig 646 return &ret, nil 647 }