gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package asymkey
  4. import (
  5. "bytes"
  6. "crypto"
  7. "encoding/base64"
  8. "errors"
  9. "fmt"
  10. "hash"
  11. "io"
  12. "strings"
  13. "time"
  14. "github.com/ProtonMail/go-crypto/openpgp"
  15. "github.com/ProtonMail/go-crypto/openpgp/armor"
  16. "github.com/ProtonMail/go-crypto/openpgp/packet"
  17. )
  18. // __________________ ________ ____ __.
  19. // / _____/\______ \/ _____/ | |/ _|____ ___.__.
  20. // / \ ___ | ___/ \ ___ | <_/ __ < | |
  21. // \ \_\ \| | \ \_\ \ | | \ ___/\___ |
  22. // \______ /|____| \______ / |____|__ \___ > ____|
  23. // \/ \/ \/ \/\/
  24. // _________
  25. // \_ ___ \ ____ _____ _____ ____ ____
  26. // / \ \/ / _ \ / \ / \ / _ \ / \
  27. // \ \___( <_> ) Y Y \ Y Y ( <_> ) | \
  28. // \______ /\____/|__|_| /__|_| /\____/|___| /
  29. // \/ \/ \/ \/
  30. // This file provides common functions relating to GPG Keys
  31. // CheckArmoredGPGKeyString checks if the given key string is a valid GPG armored key.
  32. // The function returns the actual public key on success
  33. func CheckArmoredGPGKeyString(content string) (openpgp.EntityList, error) {
  34. list, err := openpgp.ReadArmoredKeyRing(strings.NewReader(content))
  35. if err != nil {
  36. return nil, ErrGPGKeyParsing{err}
  37. }
  38. return list, nil
  39. }
  40. // Base64EncPubKey encode public key content to base 64
  41. func Base64EncPubKey(pubkey *packet.PublicKey) (string, error) {
  42. var w bytes.Buffer
  43. err := pubkey.Serialize(&w)
  44. if err != nil {
  45. return "", err
  46. }
  47. return base64.StdEncoding.EncodeToString(w.Bytes()), nil
  48. }
  49. func readerFromBase64(s string) (io.Reader, error) {
  50. bs, err := base64.StdEncoding.DecodeString(s)
  51. if err != nil {
  52. return nil, err
  53. }
  54. return bytes.NewBuffer(bs), nil
  55. }
  56. // base64DecPubKey decode public key content from base 64
  57. func base64DecPubKey(content string) (*packet.PublicKey, error) {
  58. b, err := readerFromBase64(content)
  59. if err != nil {
  60. return nil, err
  61. }
  62. // Read key
  63. p, err := packet.Read(b)
  64. if err != nil {
  65. return nil, err
  66. }
  67. // Check type
  68. pkey, ok := p.(*packet.PublicKey)
  69. if !ok {
  70. return nil, errors.New("key is not a public key")
  71. }
  72. return pkey, nil
  73. }
  74. // getExpiryTime extract the expiry time of primary key based on sig
  75. func getExpiryTime(e *openpgp.Entity) time.Time {
  76. expiry := time.Time{}
  77. // Extract self-sign for expire date based on : https://github.com/golang/crypto/blob/master/openpgp/keys.go#L165
  78. var selfSig *packet.Signature
  79. for _, ident := range e.Identities {
  80. if selfSig == nil {
  81. selfSig = ident.SelfSignature
  82. } else if ident.SelfSignature != nil && ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
  83. selfSig = ident.SelfSignature
  84. break
  85. }
  86. }
  87. if selfSig != nil && selfSig.KeyLifetimeSecs != nil {
  88. expiry = e.PrimaryKey.CreationTime.Add(time.Duration(*selfSig.KeyLifetimeSecs) * time.Second)
  89. }
  90. return expiry
  91. }
  92. func populateHash(hashFunc crypto.Hash, msg []byte) (hash.Hash, error) {
  93. h := hashFunc.New()
  94. if _, err := h.Write(msg); err != nil {
  95. return nil, err
  96. }
  97. return h, nil
  98. }
  99. // readArmoredSign read an armored signature block with the given type. https://sourcegraph.com/github.com/golang/crypto/-/blob/openpgp/read.go#L24:6-24:17
  100. func readArmoredSign(r io.Reader) (body io.Reader, err error) {
  101. block, err := armor.Decode(r)
  102. if err != nil {
  103. return nil, err
  104. }
  105. if block.Type != openpgp.SignatureType {
  106. return nil, fmt.Errorf("expected '%s', got: %s", openpgp.SignatureType, block.Type)
  107. }
  108. return block.Body, nil
  109. }
  110. func ExtractSignature(s string) (*packet.Signature, error) {
  111. r, err := readArmoredSign(strings.NewReader(s))
  112. if err != nil {
  113. return nil, errors.New("Failed to read signature armor")
  114. }
  115. p, err := packet.Read(r)
  116. if err != nil {
  117. return nil, errors.New("Failed to read signature packet")
  118. }
  119. sig, ok := p.(*packet.Signature)
  120. if !ok {
  121. return nil, errors.New("Packet is not a signature")
  122. }
  123. return sig, nil
  124. }
  125. func TryGetKeyIDFromSignature(sig *packet.Signature) string {
  126. if sig.IssuerKeyId != nil && (*sig.IssuerKeyId) != 0 {
  127. return fmt.Sprintf("%016X", *sig.IssuerKeyId)
  128. }
  129. if len(sig.IssuerFingerprint) > 0 {
  130. return fmt.Sprintf("%016X", sig.IssuerFingerprint[12:20])
  131. }
  132. return ""
  133. }