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  }