github.com/maenmax/kairep@v0.0.0-20210218001208-55bf3df36788/src/golang.org/x/crypto/openpgp/packet/public_key_v3.go (about) 1 // Copyright 2013 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 5 package packet 6 7 import ( 8 "crypto" 9 "crypto/md5" 10 "crypto/rsa" 11 "encoding/binary" 12 "fmt" 13 "hash" 14 "io" 15 "math/big" 16 "strconv" 17 "time" 18 19 "golang.org/x/crypto/openpgp/errors" 20 ) 21 22 // PublicKeyV3 represents older, version 3 public keys. These keys are less secure and 23 // should not be used for signing or encrypting. They are supported here only for 24 // parsing version 3 key material and validating signatures. 25 // See RFC 4880, section 5.5.2. 26 type PublicKeyV3 struct { 27 CreationTime time.Time 28 DaysToExpire uint16 29 PubKeyAlgo PublicKeyAlgorithm 30 PublicKey *rsa.PublicKey 31 Fingerprint [16]byte 32 KeyId uint64 33 IsSubkey bool 34 35 n, e parsedMPI 36 } 37 38 // newRSAPublicKeyV3 returns a PublicKey that wraps the given rsa.PublicKey. 39 // Included here for testing purposes only. RFC 4880, section 5.5.2: 40 // "an implementation MUST NOT generate a V3 key, but MAY accept it." 41 func newRSAPublicKeyV3(creationTime time.Time, pub *rsa.PublicKey) *PublicKeyV3 { 42 pk := &PublicKeyV3{ 43 CreationTime: creationTime, 44 PublicKey: pub, 45 n: fromBig(pub.N), 46 e: fromBig(big.NewInt(int64(pub.E))), 47 } 48 49 pk.setFingerPrintAndKeyId() 50 return pk 51 } 52 53 func (pk *PublicKeyV3) parse(r io.Reader) (err error) { 54 // RFC 4880, section 5.5.2 55 var buf [8]byte 56 if _, err = readFull(r, buf[:]); err != nil { 57 return 58 } 59 if buf[0] < 2 || buf[0] > 3 { 60 return errors.UnsupportedError("public key version") 61 } 62 pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0) 63 pk.DaysToExpire = binary.BigEndian.Uint16(buf[5:7]) 64 pk.PubKeyAlgo = PublicKeyAlgorithm(buf[7]) 65 switch pk.PubKeyAlgo { 66 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: 67 err = pk.parseRSA(r) 68 default: 69 err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo))) 70 } 71 if err != nil { 72 return 73 } 74 75 pk.setFingerPrintAndKeyId() 76 return 77 } 78 79 func (pk *PublicKeyV3) setFingerPrintAndKeyId() { 80 // RFC 4880, section 12.2 81 fingerPrint := md5.New() 82 fingerPrint.Write(pk.n.bytes) 83 fingerPrint.Write(pk.e.bytes) 84 fingerPrint.Sum(pk.Fingerprint[:0]) 85 pk.KeyId = binary.BigEndian.Uint64(pk.n.bytes[len(pk.n.bytes)-8:]) 86 } 87 88 // parseRSA parses RSA public key material from the given Reader. See RFC 4880, 89 // section 5.5.2. 90 func (pk *PublicKeyV3) parseRSA(r io.Reader) (err error) { 91 if pk.n.bytes, pk.n.bitLength, err = readMPI(r); err != nil { 92 return 93 } 94 if pk.e.bytes, pk.e.bitLength, err = readMPI(r); err != nil { 95 return 96 } 97 98 // RFC 4880 Section 12.2 requires the low 8 bytes of the 99 // modulus to form the key id. 100 if len(pk.n.bytes) < 8 { 101 return errors.StructuralError("v3 public key modulus is too short") 102 } 103 if len(pk.e.bytes) > 3 { 104 err = errors.UnsupportedError("large public exponent") 105 return 106 } 107 rsa := &rsa.PublicKey{N: new(big.Int).SetBytes(pk.n.bytes)} 108 for i := 0; i < len(pk.e.bytes); i++ { 109 rsa.E <<= 8 110 rsa.E |= int(pk.e.bytes[i]) 111 } 112 pk.PublicKey = rsa 113 return 114 } 115 116 // SerializeSignaturePrefix writes the prefix for this public key to the given Writer. 117 // The prefix is used when calculating a signature over this public key. See 118 // RFC 4880, section 5.2.4. 119 func (pk *PublicKeyV3) SerializeSignaturePrefix(w io.Writer) { 120 var pLength uint16 121 switch pk.PubKeyAlgo { 122 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: 123 pLength += 2 + uint16(len(pk.n.bytes)) 124 pLength += 2 + uint16(len(pk.e.bytes)) 125 default: 126 panic("unknown public key algorithm") 127 } 128 pLength += 6 129 w.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)}) 130 return 131 } 132 133 func (pk *PublicKeyV3) Serialize(w io.Writer) (err error) { 134 length := 8 // 8 byte header 135 136 switch pk.PubKeyAlgo { 137 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: 138 length += 2 + len(pk.n.bytes) 139 length += 2 + len(pk.e.bytes) 140 default: 141 panic("unknown public key algorithm") 142 } 143 144 packetType := packetTypePublicKey 145 if pk.IsSubkey { 146 packetType = packetTypePublicSubkey 147 } 148 if err = serializeHeader(w, packetType, length); err != nil { 149 return 150 } 151 return pk.serializeWithoutHeaders(w) 152 } 153 154 // serializeWithoutHeaders marshals the PublicKey to w in the form of an 155 // OpenPGP public key packet, not including the packet header. 156 func (pk *PublicKeyV3) serializeWithoutHeaders(w io.Writer) (err error) { 157 var buf [8]byte 158 // Version 3 159 buf[0] = 3 160 // Creation time 161 t := uint32(pk.CreationTime.Unix()) 162 buf[1] = byte(t >> 24) 163 buf[2] = byte(t >> 16) 164 buf[3] = byte(t >> 8) 165 buf[4] = byte(t) 166 // Days to expire 167 buf[5] = byte(pk.DaysToExpire >> 8) 168 buf[6] = byte(pk.DaysToExpire) 169 // Public key algorithm 170 buf[7] = byte(pk.PubKeyAlgo) 171 172 if _, err = w.Write(buf[:]); err != nil { 173 return 174 } 175 176 switch pk.PubKeyAlgo { 177 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: 178 return writeMPIs(w, pk.n, pk.e) 179 } 180 return errors.InvalidArgumentError("bad public-key algorithm") 181 } 182 183 // CanSign returns true iff this public key can generate signatures 184 func (pk *PublicKeyV3) CanSign() bool { 185 return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly 186 } 187 188 // VerifySignatureV3 returns nil iff sig is a valid signature, made by this 189 // public key, of the data hashed into signed. signed is mutated by this call. 190 func (pk *PublicKeyV3) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) { 191 if !pk.CanSign() { 192 return errors.InvalidArgumentError("public key cannot generate signatures") 193 } 194 195 suffix := make([]byte, 5) 196 suffix[0] = byte(sig.SigType) 197 binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix())) 198 signed.Write(suffix) 199 hashBytes := signed.Sum(nil) 200 201 if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] { 202 return errors.SignatureError("hash tag doesn't match") 203 } 204 205 if pk.PubKeyAlgo != sig.PubKeyAlgo { 206 return errors.InvalidArgumentError("public key and signature use different algorithms") 207 } 208 209 switch pk.PubKeyAlgo { 210 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: 211 if err = rsa.VerifyPKCS1v15(pk.PublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil { 212 return errors.SignatureError("RSA verification failure") 213 } 214 return 215 default: 216 // V3 public keys only support RSA. 217 panic("shouldn't happen") 218 } 219 panic("unreachable") 220 } 221 222 // VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this 223 // public key, that id is the identity of pub. 224 func (pk *PublicKeyV3) VerifyUserIdSignatureV3(id string, pub *PublicKeyV3, sig *SignatureV3) (err error) { 225 h, err := userIdSignatureV3Hash(id, pk, sig.Hash) 226 if err != nil { 227 return err 228 } 229 return pk.VerifySignatureV3(h, sig) 230 } 231 232 // VerifyKeySignatureV3 returns nil iff sig is a valid signature, made by this 233 // public key, of signed. 234 func (pk *PublicKeyV3) VerifyKeySignatureV3(signed *PublicKeyV3, sig *SignatureV3) (err error) { 235 h, err := keySignatureHash(pk, signed, sig.Hash) 236 if err != nil { 237 return err 238 } 239 return pk.VerifySignatureV3(h, sig) 240 } 241 242 // userIdSignatureV3Hash returns a Hash of the message that needs to be signed 243 // to assert that pk is a valid key for id. 244 func userIdSignatureV3Hash(id string, pk signingKey, hfn crypto.Hash) (h hash.Hash, err error) { 245 if !hfn.Available() { 246 return nil, errors.UnsupportedError("hash function") 247 } 248 h = hfn.New() 249 250 // RFC 4880, section 5.2.4 251 pk.SerializeSignaturePrefix(h) 252 pk.serializeWithoutHeaders(h) 253 254 h.Write([]byte(id)) 255 256 return 257 } 258 259 // KeyIdString returns the public key's fingerprint in capital hex 260 // (e.g. "6C7EE1B8621CC013"). 261 func (pk *PublicKeyV3) KeyIdString() string { 262 return fmt.Sprintf("%X", pk.KeyId) 263 } 264 265 // KeyIdShortString returns the short form of public key's fingerprint 266 // in capital hex, as shown by gpg --list-keys (e.g. "621CC013"). 267 func (pk *PublicKeyV3) KeyIdShortString() string { 268 return fmt.Sprintf("%X", pk.KeyId&0xFFFFFFFF) 269 } 270 271 // BitLength returns the bit length for the given public key. 272 func (pk *PublicKeyV3) BitLength() (bitLength uint16, err error) { 273 switch pk.PubKeyAlgo { 274 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: 275 bitLength = pk.n.bitLength 276 default: 277 err = errors.InvalidArgumentError("bad public-key algorithm") 278 } 279 return 280 }