本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

694 lines
19KB

  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package openpgp
  5. import (
  6. "crypto/rsa"
  7. "io"
  8. "time"
  9. "golang.org/x/crypto/openpgp/armor"
  10. "golang.org/x/crypto/openpgp/errors"
  11. "golang.org/x/crypto/openpgp/packet"
  12. )
  13. // PublicKeyType is the armor type for a PGP public key.
  14. var PublicKeyType = "PGP PUBLIC KEY BLOCK"
  15. // PrivateKeyType is the armor type for a PGP private key.
  16. var PrivateKeyType = "PGP PRIVATE KEY BLOCK"
  17. // An Entity represents the components of an OpenPGP key: a primary public key
  18. // (which must be a signing key), one or more identities claimed by that key,
  19. // and zero or more subkeys, which may be encryption keys.
  20. type Entity struct {
  21. PrimaryKey *packet.PublicKey
  22. PrivateKey *packet.PrivateKey
  23. Identities map[string]*Identity // indexed by Identity.Name
  24. Revocations []*packet.Signature
  25. Subkeys []Subkey
  26. }
  27. // An Identity represents an identity claimed by an Entity and zero or more
  28. // assertions by other entities about that claim.
  29. type Identity struct {
  30. Name string // by convention, has the form "Full Name (comment) <email@example.com>"
  31. UserId *packet.UserId
  32. SelfSignature *packet.Signature
  33. Signatures []*packet.Signature
  34. }
  35. // A Subkey is an additional public key in an Entity. Subkeys can be used for
  36. // encryption.
  37. type Subkey struct {
  38. PublicKey *packet.PublicKey
  39. PrivateKey *packet.PrivateKey
  40. Sig *packet.Signature
  41. }
  42. // A Key identifies a specific public key in an Entity. This is either the
  43. // Entity's primary key or a subkey.
  44. type Key struct {
  45. Entity *Entity
  46. PublicKey *packet.PublicKey
  47. PrivateKey *packet.PrivateKey
  48. SelfSignature *packet.Signature
  49. }
  50. // A KeyRing provides access to public and private keys.
  51. type KeyRing interface {
  52. // KeysById returns the set of keys that have the given key id.
  53. KeysById(id uint64) []Key
  54. // KeysByIdAndUsage returns the set of keys with the given id
  55. // that also meet the key usage given by requiredUsage.
  56. // The requiredUsage is expressed as the bitwise-OR of
  57. // packet.KeyFlag* values.
  58. KeysByIdUsage(id uint64, requiredUsage byte) []Key
  59. // DecryptionKeys returns all private keys that are valid for
  60. // decryption.
  61. DecryptionKeys() []Key
  62. }
  63. // primaryIdentity returns the Identity marked as primary or the first identity
  64. // if none are so marked.
  65. func (e *Entity) primaryIdentity() *Identity {
  66. var firstIdentity *Identity
  67. for _, ident := range e.Identities {
  68. if firstIdentity == nil {
  69. firstIdentity = ident
  70. }
  71. if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
  72. return ident
  73. }
  74. }
  75. return firstIdentity
  76. }
  77. // encryptionKey returns the best candidate Key for encrypting a message to the
  78. // given Entity.
  79. func (e *Entity) encryptionKey(now time.Time) (Key, bool) {
  80. candidateSubkey := -1
  81. // Iterate the keys to find the newest key
  82. var maxTime time.Time
  83. for i, subkey := range e.Subkeys {
  84. if subkey.Sig.FlagsValid &&
  85. subkey.Sig.FlagEncryptCommunications &&
  86. subkey.PublicKey.PubKeyAlgo.CanEncrypt() &&
  87. !subkey.Sig.KeyExpired(now) &&
  88. (maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) {
  89. candidateSubkey = i
  90. maxTime = subkey.Sig.CreationTime
  91. }
  92. }
  93. if candidateSubkey != -1 {
  94. subkey := e.Subkeys[candidateSubkey]
  95. return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}, true
  96. }
  97. // If we don't have any candidate subkeys for encryption and
  98. // the primary key doesn't have any usage metadata then we
  99. // assume that the primary key is ok. Or, if the primary key is
  100. // marked as ok to encrypt to, then we can obviously use it.
  101. i := e.primaryIdentity()
  102. if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagEncryptCommunications &&
  103. e.PrimaryKey.PubKeyAlgo.CanEncrypt() &&
  104. !i.SelfSignature.KeyExpired(now) {
  105. return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}, true
  106. }
  107. // This Entity appears to be signing only.
  108. return Key{}, false
  109. }
  110. // signingKey return the best candidate Key for signing a message with this
  111. // Entity.
  112. func (e *Entity) signingKey(now time.Time) (Key, bool) {
  113. candidateSubkey := -1
  114. for i, subkey := range e.Subkeys {
  115. if subkey.Sig.FlagsValid &&
  116. subkey.Sig.FlagSign &&
  117. subkey.PublicKey.PubKeyAlgo.CanSign() &&
  118. !subkey.Sig.KeyExpired(now) {
  119. candidateSubkey = i
  120. break
  121. }
  122. }
  123. if candidateSubkey != -1 {
  124. subkey := e.Subkeys[candidateSubkey]
  125. return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}, true
  126. }
  127. // If we have no candidate subkey then we assume that it's ok to sign
  128. // with the primary key.
  129. i := e.primaryIdentity()
  130. if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagSign &&
  131. !i.SelfSignature.KeyExpired(now) {
  132. return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}, true
  133. }
  134. return Key{}, false
  135. }
  136. // An EntityList contains one or more Entities.
  137. type EntityList []*Entity
  138. // KeysById returns the set of keys that have the given key id.
  139. func (el EntityList) KeysById(id uint64) (keys []Key) {
  140. for _, e := range el {
  141. if e.PrimaryKey.KeyId == id {
  142. var selfSig *packet.Signature
  143. for _, ident := range e.Identities {
  144. if selfSig == nil {
  145. selfSig = ident.SelfSignature
  146. } else if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
  147. selfSig = ident.SelfSignature
  148. break
  149. }
  150. }
  151. keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig})
  152. }
  153. for _, subKey := range e.Subkeys {
  154. if subKey.PublicKey.KeyId == id {
  155. keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
  156. }
  157. }
  158. }
  159. return
  160. }
  161. // KeysByIdAndUsage returns the set of keys with the given id that also meet
  162. // the key usage given by requiredUsage. The requiredUsage is expressed as
  163. // the bitwise-OR of packet.KeyFlag* values.
  164. func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key) {
  165. for _, key := range el.KeysById(id) {
  166. if len(key.Entity.Revocations) > 0 {
  167. continue
  168. }
  169. if key.SelfSignature.RevocationReason != nil {
  170. continue
  171. }
  172. if key.SelfSignature.FlagsValid && requiredUsage != 0 {
  173. var usage byte
  174. if key.SelfSignature.FlagCertify {
  175. usage |= packet.KeyFlagCertify
  176. }
  177. if key.SelfSignature.FlagSign {
  178. usage |= packet.KeyFlagSign
  179. }
  180. if key.SelfSignature.FlagEncryptCommunications {
  181. usage |= packet.KeyFlagEncryptCommunications
  182. }
  183. if key.SelfSignature.FlagEncryptStorage {
  184. usage |= packet.KeyFlagEncryptStorage
  185. }
  186. if usage&requiredUsage != requiredUsage {
  187. continue
  188. }
  189. }
  190. keys = append(keys, key)
  191. }
  192. return
  193. }
  194. // DecryptionKeys returns all private keys that are valid for decryption.
  195. func (el EntityList) DecryptionKeys() (keys []Key) {
  196. for _, e := range el {
  197. for _, subKey := range e.Subkeys {
  198. if subKey.PrivateKey != nil && (!subKey.Sig.FlagsValid || subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) {
  199. keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
  200. }
  201. }
  202. }
  203. return
  204. }
  205. // ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file.
  206. func ReadArmoredKeyRing(r io.Reader) (EntityList, error) {
  207. block, err := armor.Decode(r)
  208. if err == io.EOF {
  209. return nil, errors.InvalidArgumentError("no armored data found")
  210. }
  211. if err != nil {
  212. return nil, err
  213. }
  214. if block.Type != PublicKeyType && block.Type != PrivateKeyType {
  215. return nil, errors.InvalidArgumentError("expected public or private key block, got: " + block.Type)
  216. }
  217. return ReadKeyRing(block.Body)
  218. }
  219. // ReadKeyRing reads one or more public/private keys. Unsupported keys are
  220. // ignored as long as at least a single valid key is found.
  221. func ReadKeyRing(r io.Reader) (el EntityList, err error) {
  222. packets := packet.NewReader(r)
  223. var lastUnsupportedError error
  224. for {
  225. var e *Entity
  226. e, err = ReadEntity(packets)
  227. if err != nil {
  228. // TODO: warn about skipped unsupported/unreadable keys
  229. if _, ok := err.(errors.UnsupportedError); ok {
  230. lastUnsupportedError = err
  231. err = readToNextPublicKey(packets)
  232. } else if _, ok := err.(errors.StructuralError); ok {
  233. // Skip unreadable, badly-formatted keys
  234. lastUnsupportedError = err
  235. err = readToNextPublicKey(packets)
  236. }
  237. if err == io.EOF {
  238. err = nil
  239. break
  240. }
  241. if err != nil {
  242. el = nil
  243. break
  244. }
  245. } else {
  246. el = append(el, e)
  247. }
  248. }
  249. if len(el) == 0 && err == nil {
  250. err = lastUnsupportedError
  251. }
  252. return
  253. }
  254. // readToNextPublicKey reads packets until the start of the entity and leaves
  255. // the first packet of the new entity in the Reader.
  256. func readToNextPublicKey(packets *packet.Reader) (err error) {
  257. var p packet.Packet
  258. for {
  259. p, err = packets.Next()
  260. if err == io.EOF {
  261. return
  262. } else if err != nil {
  263. if _, ok := err.(errors.UnsupportedError); ok {
  264. err = nil
  265. continue
  266. }
  267. return
  268. }
  269. if pk, ok := p.(*packet.PublicKey); ok && !pk.IsSubkey {
  270. packets.Unread(p)
  271. return
  272. }
  273. }
  274. }
  275. // ReadEntity reads an entity (public key, identities, subkeys etc) from the
  276. // given Reader.
  277. func ReadEntity(packets *packet.Reader) (*Entity, error) {
  278. e := new(Entity)
  279. e.Identities = make(map[string]*Identity)
  280. p, err := packets.Next()
  281. if err != nil {
  282. return nil, err
  283. }
  284. var ok bool
  285. if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok {
  286. if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok {
  287. packets.Unread(p)
  288. return nil, errors.StructuralError("first packet was not a public/private key")
  289. }
  290. e.PrimaryKey = &e.PrivateKey.PublicKey
  291. }
  292. if !e.PrimaryKey.PubKeyAlgo.CanSign() {
  293. return nil, errors.StructuralError("primary key cannot be used for signatures")
  294. }
  295. var revocations []*packet.Signature
  296. EachPacket:
  297. for {
  298. p, err := packets.Next()
  299. if err == io.EOF {
  300. break
  301. } else if err != nil {
  302. return nil, err
  303. }
  304. switch pkt := p.(type) {
  305. case *packet.UserId:
  306. if err := addUserID(e, packets, pkt); err != nil {
  307. return nil, err
  308. }
  309. case *packet.Signature:
  310. if pkt.SigType == packet.SigTypeKeyRevocation {
  311. revocations = append(revocations, pkt)
  312. } else if pkt.SigType == packet.SigTypeDirectSignature {
  313. // TODO: RFC4880 5.2.1 permits signatures
  314. // directly on keys (eg. to bind additional
  315. // revocation keys).
  316. }
  317. // Else, ignoring the signature as it does not follow anything
  318. // we would know to attach it to.
  319. case *packet.PrivateKey:
  320. if pkt.IsSubkey == false {
  321. packets.Unread(p)
  322. break EachPacket
  323. }
  324. err = addSubkey(e, packets, &pkt.PublicKey, pkt)
  325. if err != nil {
  326. return nil, err
  327. }
  328. case *packet.PublicKey:
  329. if pkt.IsSubkey == false {
  330. packets.Unread(p)
  331. break EachPacket
  332. }
  333. err = addSubkey(e, packets, pkt, nil)
  334. if err != nil {
  335. return nil, err
  336. }
  337. default:
  338. // we ignore unknown packets
  339. }
  340. }
  341. if len(e.Identities) == 0 {
  342. return nil, errors.StructuralError("entity without any identities")
  343. }
  344. for _, revocation := range revocations {
  345. err = e.PrimaryKey.VerifyRevocationSignature(revocation)
  346. if err == nil {
  347. e.Revocations = append(e.Revocations, revocation)
  348. } else {
  349. // TODO: RFC 4880 5.2.3.15 defines revocation keys.
  350. return nil, errors.StructuralError("revocation signature signed by alternate key")
  351. }
  352. }
  353. return e, nil
  354. }
  355. func addUserID(e *Entity, packets *packet.Reader, pkt *packet.UserId) error {
  356. // Make a new Identity object, that we might wind up throwing away.
  357. // We'll only add it if we get a valid self-signature over this
  358. // userID.
  359. identity := new(Identity)
  360. identity.Name = pkt.Id
  361. identity.UserId = pkt
  362. for {
  363. p, err := packets.Next()
  364. if err == io.EOF {
  365. break
  366. } else if err != nil {
  367. return err
  368. }
  369. sig, ok := p.(*packet.Signature)
  370. if !ok {
  371. packets.Unread(p)
  372. break
  373. }
  374. if (sig.SigType == packet.SigTypePositiveCert || sig.SigType == packet.SigTypeGenericCert) && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId {
  375. if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, e.PrimaryKey, sig); err != nil {
  376. return errors.StructuralError("user ID self-signature invalid: " + err.Error())
  377. }
  378. identity.SelfSignature = sig
  379. e.Identities[pkt.Id] = identity
  380. } else {
  381. identity.Signatures = append(identity.Signatures, sig)
  382. }
  383. }
  384. return nil
  385. }
  386. func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error {
  387. var subKey Subkey
  388. subKey.PublicKey = pub
  389. subKey.PrivateKey = priv
  390. for {
  391. p, err := packets.Next()
  392. if err == io.EOF {
  393. break
  394. } else if err != nil {
  395. return errors.StructuralError("subkey signature invalid: " + err.Error())
  396. }
  397. sig, ok := p.(*packet.Signature)
  398. if !ok {
  399. packets.Unread(p)
  400. break
  401. }
  402. if sig.SigType != packet.SigTypeSubkeyBinding && sig.SigType != packet.SigTypeSubkeyRevocation {
  403. return errors.StructuralError("subkey signature with wrong type")
  404. }
  405. if err := e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, sig); err != nil {
  406. return errors.StructuralError("subkey signature invalid: " + err.Error())
  407. }
  408. switch sig.SigType {
  409. case packet.SigTypeSubkeyRevocation:
  410. subKey.Sig = sig
  411. case packet.SigTypeSubkeyBinding:
  412. if shouldReplaceSubkeySig(subKey.Sig, sig) {
  413. subKey.Sig = sig
  414. }
  415. }
  416. }
  417. if subKey.Sig == nil {
  418. return errors.StructuralError("subkey packet not followed by signature")
  419. }
  420. e.Subkeys = append(e.Subkeys, subKey)
  421. return nil
  422. }
  423. func shouldReplaceSubkeySig(existingSig, potentialNewSig *packet.Signature) bool {
  424. if potentialNewSig == nil {
  425. return false
  426. }
  427. if existingSig == nil {
  428. return true
  429. }
  430. if existingSig.SigType == packet.SigTypeSubkeyRevocation {
  431. return false // never override a revocation signature
  432. }
  433. return potentialNewSig.CreationTime.After(existingSig.CreationTime)
  434. }
  435. const defaultRSAKeyBits = 2048
  436. // NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a
  437. // single identity composed of the given full name, comment and email, any of
  438. // which may be empty but must not contain any of "()<>\x00".
  439. // If config is nil, sensible defaults will be used.
  440. func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
  441. creationTime := config.Now()
  442. bits := defaultRSAKeyBits
  443. if config != nil && config.RSABits != 0 {
  444. bits = config.RSABits
  445. }
  446. uid := packet.NewUserId(name, comment, email)
  447. if uid == nil {
  448. return nil, errors.InvalidArgumentError("user id field contained invalid characters")
  449. }
  450. signingPriv, err := rsa.GenerateKey(config.Random(), bits)
  451. if err != nil {
  452. return nil, err
  453. }
  454. encryptingPriv, err := rsa.GenerateKey(config.Random(), bits)
  455. if err != nil {
  456. return nil, err
  457. }
  458. e := &Entity{
  459. PrimaryKey: packet.NewRSAPublicKey(creationTime, &signingPriv.PublicKey),
  460. PrivateKey: packet.NewRSAPrivateKey(creationTime, signingPriv),
  461. Identities: make(map[string]*Identity),
  462. }
  463. isPrimaryId := true
  464. e.Identities[uid.Id] = &Identity{
  465. Name: uid.Id,
  466. UserId: uid,
  467. SelfSignature: &packet.Signature{
  468. CreationTime: creationTime,
  469. SigType: packet.SigTypePositiveCert,
  470. PubKeyAlgo: packet.PubKeyAlgoRSA,
  471. Hash: config.Hash(),
  472. IsPrimaryId: &isPrimaryId,
  473. FlagsValid: true,
  474. FlagSign: true,
  475. FlagCertify: true,
  476. IssuerKeyId: &e.PrimaryKey.KeyId,
  477. },
  478. }
  479. err = e.Identities[uid.Id].SelfSignature.SignUserId(uid.Id, e.PrimaryKey, e.PrivateKey, config)
  480. if err != nil {
  481. return nil, err
  482. }
  483. // If the user passes in a DefaultHash via packet.Config,
  484. // set the PreferredHash for the SelfSignature.
  485. if config != nil && config.DefaultHash != 0 {
  486. e.Identities[uid.Id].SelfSignature.PreferredHash = []uint8{hashToHashId(config.DefaultHash)}
  487. }
  488. // Likewise for DefaultCipher.
  489. if config != nil && config.DefaultCipher != 0 {
  490. e.Identities[uid.Id].SelfSignature.PreferredSymmetric = []uint8{uint8(config.DefaultCipher)}
  491. }
  492. e.Subkeys = make([]Subkey, 1)
  493. e.Subkeys[0] = Subkey{
  494. PublicKey: packet.NewRSAPublicKey(creationTime, &encryptingPriv.PublicKey),
  495. PrivateKey: packet.NewRSAPrivateKey(creationTime, encryptingPriv),
  496. Sig: &packet.Signature{
  497. CreationTime: creationTime,
  498. SigType: packet.SigTypeSubkeyBinding,
  499. PubKeyAlgo: packet.PubKeyAlgoRSA,
  500. Hash: config.Hash(),
  501. FlagsValid: true,
  502. FlagEncryptStorage: true,
  503. FlagEncryptCommunications: true,
  504. IssuerKeyId: &e.PrimaryKey.KeyId,
  505. },
  506. }
  507. e.Subkeys[0].PublicKey.IsSubkey = true
  508. e.Subkeys[0].PrivateKey.IsSubkey = true
  509. err = e.Subkeys[0].Sig.SignKey(e.Subkeys[0].PublicKey, e.PrivateKey, config)
  510. if err != nil {
  511. return nil, err
  512. }
  513. return e, nil
  514. }
  515. // SerializePrivate serializes an Entity, including private key material, but
  516. // excluding signatures from other entities, to the given Writer.
  517. // Identities and subkeys are re-signed in case they changed since NewEntry.
  518. // If config is nil, sensible defaults will be used.
  519. func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) {
  520. err = e.PrivateKey.Serialize(w)
  521. if err != nil {
  522. return
  523. }
  524. for _, ident := range e.Identities {
  525. err = ident.UserId.Serialize(w)
  526. if err != nil {
  527. return
  528. }
  529. err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey, config)
  530. if err != nil {
  531. return
  532. }
  533. err = ident.SelfSignature.Serialize(w)
  534. if err != nil {
  535. return
  536. }
  537. }
  538. for _, subkey := range e.Subkeys {
  539. err = subkey.PrivateKey.Serialize(w)
  540. if err != nil {
  541. return
  542. }
  543. err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
  544. if err != nil {
  545. return
  546. }
  547. err = subkey.Sig.Serialize(w)
  548. if err != nil {
  549. return
  550. }
  551. }
  552. return nil
  553. }
  554. // Serialize writes the public part of the given Entity to w, including
  555. // signatures from other entities. No private key material will be output.
  556. func (e *Entity) Serialize(w io.Writer) error {
  557. err := e.PrimaryKey.Serialize(w)
  558. if err != nil {
  559. return err
  560. }
  561. for _, ident := range e.Identities {
  562. err = ident.UserId.Serialize(w)
  563. if err != nil {
  564. return err
  565. }
  566. err = ident.SelfSignature.Serialize(w)
  567. if err != nil {
  568. return err
  569. }
  570. for _, sig := range ident.Signatures {
  571. err = sig.Serialize(w)
  572. if err != nil {
  573. return err
  574. }
  575. }
  576. }
  577. for _, subkey := range e.Subkeys {
  578. err = subkey.PublicKey.Serialize(w)
  579. if err != nil {
  580. return err
  581. }
  582. err = subkey.Sig.Serialize(w)
  583. if err != nil {
  584. return err
  585. }
  586. }
  587. return nil
  588. }
  589. // SignIdentity adds a signature to e, from signer, attesting that identity is
  590. // associated with e. The provided identity must already be an element of
  591. // e.Identities and the private key of signer must have been decrypted if
  592. // necessary.
  593. // If config is nil, sensible defaults will be used.
  594. func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Config) error {
  595. if signer.PrivateKey == nil {
  596. return errors.InvalidArgumentError("signing Entity must have a private key")
  597. }
  598. if signer.PrivateKey.Encrypted {
  599. return errors.InvalidArgumentError("signing Entity's private key must be decrypted")
  600. }
  601. ident, ok := e.Identities[identity]
  602. if !ok {
  603. return errors.InvalidArgumentError("given identity string not found in Entity")
  604. }
  605. sig := &packet.Signature{
  606. SigType: packet.SigTypeGenericCert,
  607. PubKeyAlgo: signer.PrivateKey.PubKeyAlgo,
  608. Hash: config.Hash(),
  609. CreationTime: config.Now(),
  610. IssuerKeyId: &signer.PrivateKey.KeyId,
  611. }
  612. if err := sig.SignUserId(identity, e.PrimaryKey, signer.PrivateKey, config); err != nil {
  613. return err
  614. }
  615. ident.Signatures = append(ident.Signatures, sig)
  616. return nil
  617. }
上海开阖软件有限公司 沪ICP备12045867号-1