github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/crypto/openpgp/packet/public_key.go (about) 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 5 package packet 6 7 import ( 8 "bytes" 9 "crypto" 10 "crypto/dsa" 11 "crypto/ecdsa" 12 "crypto/elliptic" 13 "crypto/rsa" 14 "crypto/sha1" 15 _ "crypto/sha256" 16 _ "crypto/sha512" 17 "encoding/binary" 18 "fmt" 19 "hash" 20 "io" 21 "math/big" 22 "strconv" 23 "time" 24 25 "golang.org/x/crypto/openpgp/elgamal" 26 "golang.org/x/crypto/openpgp/errors" 27 ) 28 29 var ( 30 // NIST curve P-256 31 oidCurveP256 []byte = []byte{0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07} 32 // NIST curve P-384 33 oidCurveP384 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x22} 34 // NIST curve P-521 35 oidCurveP521 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x23} 36 ) 37 38 const maxOIDLength = 8 39 40 // ecdsaKey stores the algorithm-specific fields for ECDSA keys. 41 // as defined in RFC 6637, Section 9. 42 type ecdsaKey struct { 43 // oid contains the OID byte sequence identifying the elliptic curve used 44 oid []byte 45 // p contains the elliptic curve point that represents the public key 46 p parsedMPI 47 } 48 49 // parseOID reads the OID for the curve as defined in RFC 6637, Section 9. 50 func parseOID(r io.Reader) (oid []byte, err error) { 51 buf := make([]byte, maxOIDLength) 52 if _, err = readFull(r, buf[:1]); err != nil { 53 return 54 } 55 oidLen := buf[0] 56 if int(oidLen) > len(buf) { 57 err = errors.UnsupportedError("invalid oid length: " + strconv.Itoa(int(oidLen))) 58 return 59 } 60 oid = buf[:oidLen] 61 _, err = readFull(r, oid) 62 return 63 } 64 65 func (f *ecdsaKey) parse(r io.Reader) (err error) { 66 if f.oid, err = parseOID(r); err != nil { 67 return err 68 } 69 f.p.bytes, f.p.bitLength, err = readMPI(r) 70 return 71 } 72 73 func (f *ecdsaKey) serialize(w io.Writer) (err error) { 74 buf := make([]byte, maxOIDLength+1) 75 buf[0] = byte(len(f.oid)) 76 copy(buf[1:], f.oid) 77 if _, err = w.Write(buf[:len(f.oid)+1]); err != nil { 78 return 79 } 80 return writeMPIs(w, f.p) 81 } 82 83 func (f *ecdsaKey) newECDSA() (*ecdsa.PublicKey, error) { 84 var c elliptic.Curve 85 if bytes.Equal(f.oid, oidCurveP256) { 86 c = elliptic.P256() 87 } else if bytes.Equal(f.oid, oidCurveP384) { 88 c = elliptic.P384() 89 } else if bytes.Equal(f.oid, oidCurveP521) { 90 c = elliptic.P521() 91 } else { 92 return nil, errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", f.oid)) 93 } 94 x, y := elliptic.Unmarshal(c, f.p.bytes) 95 if x == nil { 96 return nil, errors.UnsupportedError("failed to parse EC point") 97 } 98 return &ecdsa.PublicKey{Curve: c, X: x, Y: y}, nil 99 } 100 101 func (f *ecdsaKey) byteLen() int { 102 return 1 + len(f.oid) + 2 + len(f.p.bytes) 103 } 104 105 type kdfHashFunction byte 106 type kdfAlgorithm byte 107 108 // ecdhKdf stores key derivation function parameters 109 // used for ECDH encryption. See RFC 6637, Section 9. 110 type ecdhKdf struct { 111 KdfHash kdfHashFunction 112 KdfAlgo kdfAlgorithm 113 } 114 115 func (f *ecdhKdf) parse(r io.Reader) (err error) { 116 buf := make([]byte, 1) 117 if _, err = readFull(r, buf); err != nil { 118 return 119 } 120 kdfLen := int(buf[0]) 121 if kdfLen < 3 { 122 return errors.UnsupportedError("Unsupported ECDH KDF length: " + strconv.Itoa(kdfLen)) 123 } 124 buf = make([]byte, kdfLen) 125 if _, err = readFull(r, buf); err != nil { 126 return 127 } 128 reserved := int(buf[0]) 129 f.KdfHash = kdfHashFunction(buf[1]) 130 f.KdfAlgo = kdfAlgorithm(buf[2]) 131 if reserved != 0x01 { 132 return errors.UnsupportedError("Unsupported KDF reserved field: " + strconv.Itoa(reserved)) 133 } 134 return 135 } 136 137 func (f *ecdhKdf) serialize(w io.Writer) (err error) { 138 buf := make([]byte, 4) 139 // See RFC 6637, Section 9, Algorithm-Specific Fields for ECDH keys. 140 buf[0] = byte(0x03) // Length of the following fields 141 buf[1] = byte(0x01) // Reserved for future extensions, must be 1 for now 142 buf[2] = byte(f.KdfHash) 143 buf[3] = byte(f.KdfAlgo) 144 _, err = w.Write(buf[:]) 145 return 146 } 147 148 func (f *ecdhKdf) byteLen() int { 149 return 4 150 } 151 152 // PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2. 153 type PublicKey struct { 154 CreationTime time.Time 155 PubKeyAlgo PublicKeyAlgorithm 156 PublicKey interface{} // *rsa.PublicKey, *dsa.PublicKey or *ecdsa.PublicKey 157 Fingerprint [20]byte 158 KeyId uint64 159 IsSubkey bool 160 161 n, e, p, q, g, y parsedMPI 162 163 // RFC 6637 fields 164 ec *ecdsaKey 165 ecdh *ecdhKdf 166 } 167 168 // signingKey provides a convenient abstraction over signature verification 169 // for v3 and v4 public keys. 170 type signingKey interface { 171 SerializeSignaturePrefix(io.Writer) 172 serializeWithoutHeaders(io.Writer) error 173 } 174 175 func fromBig(n *big.Int) parsedMPI { 176 return parsedMPI{ 177 bytes: n.Bytes(), 178 bitLength: uint16(n.BitLen()), 179 } 180 } 181 182 // NewRSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey. 183 func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey) *PublicKey { 184 pk := &PublicKey{ 185 CreationTime: creationTime, 186 PubKeyAlgo: PubKeyAlgoRSA, 187 PublicKey: pub, 188 n: fromBig(pub.N), 189 e: fromBig(big.NewInt(int64(pub.E))), 190 } 191 192 pk.setFingerPrintAndKeyId() 193 return pk 194 } 195 196 // NewDSAPublicKey returns a PublicKey that wraps the given dsa.PublicKey. 197 func NewDSAPublicKey(creationTime time.Time, pub *dsa.PublicKey) *PublicKey { 198 pk := &PublicKey{ 199 CreationTime: creationTime, 200 PubKeyAlgo: PubKeyAlgoDSA, 201 PublicKey: pub, 202 p: fromBig(pub.P), 203 q: fromBig(pub.Q), 204 g: fromBig(pub.G), 205 y: fromBig(pub.Y), 206 } 207 208 pk.setFingerPrintAndKeyId() 209 return pk 210 } 211 212 func (pk *PublicKey) parse(r io.Reader) (err error) { 213 // RFC 4880, section 5.5.2 214 var buf [6]byte 215 _, err = readFull(r, buf[:]) 216 if err != nil { 217 return 218 } 219 if buf[0] != 4 { 220 return errors.UnsupportedError("public key version") 221 } 222 pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0) 223 pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5]) 224 switch pk.PubKeyAlgo { 225 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: 226 err = pk.parseRSA(r) 227 case PubKeyAlgoDSA: 228 err = pk.parseDSA(r) 229 case PubKeyAlgoElGamal: 230 err = pk.parseElGamal(r) 231 case PubKeyAlgoECDSA: 232 pk.ec = new(ecdsaKey) 233 if err = pk.ec.parse(r); err != nil { 234 return err 235 } 236 pk.PublicKey, err = pk.ec.newECDSA() 237 case PubKeyAlgoECDH: 238 pk.ec = new(ecdsaKey) 239 if err = pk.ec.parse(r); err != nil { 240 return 241 } 242 pk.ecdh = new(ecdhKdf) 243 if err = pk.ecdh.parse(r); err != nil { 244 return 245 } 246 // The ECDH key is stored in an ecdsa.PublicKey for convenience. 247 pk.PublicKey, err = pk.ec.newECDSA() 248 default: 249 err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo))) 250 } 251 if err != nil { 252 return 253 } 254 255 pk.setFingerPrintAndKeyId() 256 return 257 } 258 259 func (pk *PublicKey) setFingerPrintAndKeyId() { 260 // RFC 4880, section 12.2 261 fingerPrint := sha1.New() 262 pk.SerializeSignaturePrefix(fingerPrint) 263 pk.serializeWithoutHeaders(fingerPrint) 264 copy(pk.Fingerprint[:], fingerPrint.Sum(nil)) 265 pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20]) 266 } 267 268 // parseRSA parses RSA public key material from the given Reader. See RFC 4880, 269 // section 5.5.2. 270 func (pk *PublicKey) parseRSA(r io.Reader) (err error) { 271 pk.n.bytes, pk.n.bitLength, err = readMPI(r) 272 if err != nil { 273 return 274 } 275 pk.e.bytes, pk.e.bitLength, err = readMPI(r) 276 if err != nil { 277 return 278 } 279 280 if len(pk.e.bytes) > 3 { 281 err = errors.UnsupportedError("large public exponent") 282 return 283 } 284 rsa := &rsa.PublicKey{ 285 N: new(big.Int).SetBytes(pk.n.bytes), 286 E: 0, 287 } 288 for i := 0; i < len(pk.e.bytes); i++ { 289 rsa.E <<= 8 290 rsa.E |= int(pk.e.bytes[i]) 291 } 292 pk.PublicKey = rsa 293 return 294 } 295 296 // parseDSA parses DSA public key material from the given Reader. See RFC 4880, 297 // section 5.5.2. 298 func (pk *PublicKey) parseDSA(r io.Reader) (err error) { 299 pk.p.bytes, pk.p.bitLength, err = readMPI(r) 300 if err != nil { 301 return 302 } 303 pk.q.bytes, pk.q.bitLength, err = readMPI(r) 304 if err != nil { 305 return 306 } 307 pk.g.bytes, pk.g.bitLength, err = readMPI(r) 308 if err != nil { 309 return 310 } 311 pk.y.bytes, pk.y.bitLength, err = readMPI(r) 312 if err != nil { 313 return 314 } 315 316 dsa := new(dsa.PublicKey) 317 dsa.P = new(big.Int).SetBytes(pk.p.bytes) 318 dsa.Q = new(big.Int).SetBytes(pk.q.bytes) 319 dsa.G = new(big.Int).SetBytes(pk.g.bytes) 320 dsa.Y = new(big.Int).SetBytes(pk.y.bytes) 321 pk.PublicKey = dsa 322 return 323 } 324 325 // parseElGamal parses ElGamal public key material from the given Reader. See 326 // RFC 4880, section 5.5.2. 327 func (pk *PublicKey) parseElGamal(r io.Reader) (err error) { 328 pk.p.bytes, pk.p.bitLength, err = readMPI(r) 329 if err != nil { 330 return 331 } 332 pk.g.bytes, pk.g.bitLength, err = readMPI(r) 333 if err != nil { 334 return 335 } 336 pk.y.bytes, pk.y.bitLength, err = readMPI(r) 337 if err != nil { 338 return 339 } 340 341 elgamal := new(elgamal.PublicKey) 342 elgamal.P = new(big.Int).SetBytes(pk.p.bytes) 343 elgamal.G = new(big.Int).SetBytes(pk.g.bytes) 344 elgamal.Y = new(big.Int).SetBytes(pk.y.bytes) 345 pk.PublicKey = elgamal 346 return 347 } 348 349 // SerializeSignaturePrefix writes the prefix for this public key to the given Writer. 350 // The prefix is used when calculating a signature over this public key. See 351 // RFC 4880, section 5.2.4. 352 func (pk *PublicKey) SerializeSignaturePrefix(h io.Writer) { 353 var pLength uint16 354 switch pk.PubKeyAlgo { 355 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: 356 pLength += 2 + uint16(len(pk.n.bytes)) 357 pLength += 2 + uint16(len(pk.e.bytes)) 358 case PubKeyAlgoDSA: 359 pLength += 2 + uint16(len(pk.p.bytes)) 360 pLength += 2 + uint16(len(pk.q.bytes)) 361 pLength += 2 + uint16(len(pk.g.bytes)) 362 pLength += 2 + uint16(len(pk.y.bytes)) 363 case PubKeyAlgoElGamal: 364 pLength += 2 + uint16(len(pk.p.bytes)) 365 pLength += 2 + uint16(len(pk.g.bytes)) 366 pLength += 2 + uint16(len(pk.y.bytes)) 367 case PubKeyAlgoECDSA: 368 pLength += uint16(pk.ec.byteLen()) 369 case PubKeyAlgoECDH: 370 pLength += uint16(pk.ec.byteLen()) 371 pLength += uint16(pk.ecdh.byteLen()) 372 default: 373 panic("unknown public key algorithm") 374 } 375 pLength += 6 376 h.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)}) 377 return 378 } 379 380 func (pk *PublicKey) Serialize(w io.Writer) (err error) { 381 length := 6 // 6 byte header 382 383 switch pk.PubKeyAlgo { 384 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: 385 length += 2 + len(pk.n.bytes) 386 length += 2 + len(pk.e.bytes) 387 case PubKeyAlgoDSA: 388 length += 2 + len(pk.p.bytes) 389 length += 2 + len(pk.q.bytes) 390 length += 2 + len(pk.g.bytes) 391 length += 2 + len(pk.y.bytes) 392 case PubKeyAlgoElGamal: 393 length += 2 + len(pk.p.bytes) 394 length += 2 + len(pk.g.bytes) 395 length += 2 + len(pk.y.bytes) 396 case PubKeyAlgoECDSA: 397 length += pk.ec.byteLen() 398 case PubKeyAlgoECDH: 399 length += pk.ec.byteLen() 400 length += pk.ecdh.byteLen() 401 default: 402 panic("unknown public key algorithm") 403 } 404 405 packetType := packetTypePublicKey 406 if pk.IsSubkey { 407 packetType = packetTypePublicSubkey 408 } 409 err = serializeHeader(w, packetType, length) 410 if err != nil { 411 return 412 } 413 return pk.serializeWithoutHeaders(w) 414 } 415 416 // serializeWithoutHeaders marshals the PublicKey to w in the form of an 417 // OpenPGP public key packet, not including the packet header. 418 func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) { 419 var buf [6]byte 420 buf[0] = 4 421 t := uint32(pk.CreationTime.Unix()) 422 buf[1] = byte(t >> 24) 423 buf[2] = byte(t >> 16) 424 buf[3] = byte(t >> 8) 425 buf[4] = byte(t) 426 buf[5] = byte(pk.PubKeyAlgo) 427 428 _, err = w.Write(buf[:]) 429 if err != nil { 430 return 431 } 432 433 switch pk.PubKeyAlgo { 434 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: 435 return writeMPIs(w, pk.n, pk.e) 436 case PubKeyAlgoDSA: 437 return writeMPIs(w, pk.p, pk.q, pk.g, pk.y) 438 case PubKeyAlgoElGamal: 439 return writeMPIs(w, pk.p, pk.g, pk.y) 440 case PubKeyAlgoECDSA: 441 return pk.ec.serialize(w) 442 case PubKeyAlgoECDH: 443 if err = pk.ec.serialize(w); err != nil { 444 return 445 } 446 return pk.ecdh.serialize(w) 447 } 448 return errors.InvalidArgumentError("bad public-key algorithm") 449 } 450 451 // CanSign returns true iff this public key can generate signatures 452 func (pk *PublicKey) CanSign() bool { 453 return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElGamal 454 } 455 456 // VerifySignature returns nil iff sig is a valid signature, made by this 457 // public key, of the data hashed into signed. signed is mutated by this call. 458 func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) { 459 if !pk.CanSign() { 460 return errors.InvalidArgumentError("public key cannot generate signatures") 461 } 462 463 signed.Write(sig.HashSuffix) 464 hashBytes := signed.Sum(nil) 465 466 if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] { 467 return errors.SignatureError("hash tag doesn't match") 468 } 469 470 if pk.PubKeyAlgo != sig.PubKeyAlgo { 471 return errors.InvalidArgumentError("public key and signature use different algorithms") 472 } 473 474 switch pk.PubKeyAlgo { 475 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: 476 rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey) 477 err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes) 478 if err != nil { 479 return errors.SignatureError("RSA verification failure") 480 } 481 return nil 482 case PubKeyAlgoDSA: 483 dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey) 484 // Need to truncate hashBytes to match FIPS 186-3 section 4.6. 485 subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8 486 if len(hashBytes) > subgroupSize { 487 hashBytes = hashBytes[:subgroupSize] 488 } 489 if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) { 490 return errors.SignatureError("DSA verification failure") 491 } 492 return nil 493 case PubKeyAlgoECDSA: 494 ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey) 495 if !ecdsa.Verify(ecdsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.ECDSASigR.bytes), new(big.Int).SetBytes(sig.ECDSASigS.bytes)) { 496 return errors.SignatureError("ECDSA verification failure") 497 } 498 return nil 499 default: 500 return errors.SignatureError("Unsupported public key algorithm used in signature") 501 } 502 panic("unreachable") 503 } 504 505 // VerifySignatureV3 returns nil iff sig is a valid signature, made by this 506 // public key, of the data hashed into signed. signed is mutated by this call. 507 func (pk *PublicKey) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) { 508 if !pk.CanSign() { 509 return errors.InvalidArgumentError("public key cannot generate signatures") 510 } 511 512 suffix := make([]byte, 5) 513 suffix[0] = byte(sig.SigType) 514 binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix())) 515 signed.Write(suffix) 516 hashBytes := signed.Sum(nil) 517 518 if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] { 519 return errors.SignatureError("hash tag doesn't match") 520 } 521 522 if pk.PubKeyAlgo != sig.PubKeyAlgo { 523 return errors.InvalidArgumentError("public key and signature use different algorithms") 524 } 525 526 switch pk.PubKeyAlgo { 527 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: 528 rsaPublicKey := pk.PublicKey.(*rsa.PublicKey) 529 if err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil { 530 return errors.SignatureError("RSA verification failure") 531 } 532 return 533 case PubKeyAlgoDSA: 534 dsaPublicKey := pk.PublicKey.(*dsa.PublicKey) 535 // Need to truncate hashBytes to match FIPS 186-3 section 4.6. 536 subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8 537 if len(hashBytes) > subgroupSize { 538 hashBytes = hashBytes[:subgroupSize] 539 } 540 if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) { 541 return errors.SignatureError("DSA verification failure") 542 } 543 return nil 544 default: 545 panic("shouldn't happen") 546 } 547 panic("unreachable") 548 } 549 550 // keySignatureHash returns a Hash of the message that needs to be signed for 551 // pk to assert a subkey relationship to signed. 552 func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) { 553 if !hashFunc.Available() { 554 return nil, errors.UnsupportedError("hash function") 555 } 556 h = hashFunc.New() 557 558 // RFC 4880, section 5.2.4 559 pk.SerializeSignaturePrefix(h) 560 pk.serializeWithoutHeaders(h) 561 signed.SerializeSignaturePrefix(h) 562 signed.serializeWithoutHeaders(h) 563 return 564 } 565 566 // VerifyKeySignature returns nil iff sig is a valid signature, made by this 567 // public key, of signed. 568 func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error { 569 h, err := keySignatureHash(pk, signed, sig.Hash) 570 if err != nil { 571 return err 572 } 573 if err = pk.VerifySignature(h, sig); err != nil { 574 return err 575 } 576 577 if sig.FlagSign { 578 // Signing subkeys must be cross-signed. See 579 // https://www.gnupg.org/faq/subkey-cross-certify.html. 580 if sig.EmbeddedSignature == nil { 581 return errors.StructuralError("signing subkey is missing cross-signature") 582 } 583 // Verify the cross-signature. This is calculated over the same 584 // data as the main signature, so we cannot just recursively 585 // call signed.VerifyKeySignature(...) 586 if h, err = keySignatureHash(pk, signed, sig.EmbeddedSignature.Hash); err != nil { 587 return errors.StructuralError("error while hashing for cross-signature: " + err.Error()) 588 } 589 if err := signed.VerifySignature(h, sig.EmbeddedSignature); err != nil { 590 return errors.StructuralError("error while verifying cross-signature: " + err.Error()) 591 } 592 } 593 594 return nil 595 } 596 597 func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) { 598 if !hashFunc.Available() { 599 return nil, errors.UnsupportedError("hash function") 600 } 601 h = hashFunc.New() 602 603 // RFC 4880, section 5.2.4 604 pk.SerializeSignaturePrefix(h) 605 pk.serializeWithoutHeaders(h) 606 607 return 608 } 609 610 // VerifyRevocationSignature returns nil iff sig is a valid signature, made by this 611 // public key. 612 func (pk *PublicKey) VerifyRevocationSignature(sig *Signature) (err error) { 613 h, err := keyRevocationHash(pk, sig.Hash) 614 if err != nil { 615 return err 616 } 617 return pk.VerifySignature(h, sig) 618 } 619 620 // userIdSignatureHash returns a Hash of the message that needs to be signed 621 // to assert that pk is a valid key for id. 622 func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) { 623 if !hashFunc.Available() { 624 return nil, errors.UnsupportedError("hash function") 625 } 626 h = hashFunc.New() 627 628 // RFC 4880, section 5.2.4 629 pk.SerializeSignaturePrefix(h) 630 pk.serializeWithoutHeaders(h) 631 632 var buf [5]byte 633 buf[0] = 0xb4 634 buf[1] = byte(len(id) >> 24) 635 buf[2] = byte(len(id) >> 16) 636 buf[3] = byte(len(id) >> 8) 637 buf[4] = byte(len(id)) 638 h.Write(buf[:]) 639 h.Write([]byte(id)) 640 641 return 642 } 643 644 // VerifyUserIdSignature returns nil iff sig is a valid signature, made by this 645 // public key, that id is the identity of pub. 646 func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) { 647 h, err := userIdSignatureHash(id, pub, sig.Hash) 648 if err != nil { 649 return err 650 } 651 return pk.VerifySignature(h, sig) 652 } 653 654 // VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this 655 // public key, that id is the identity of pub. 656 func (pk *PublicKey) VerifyUserIdSignatureV3(id string, pub *PublicKey, sig *SignatureV3) (err error) { 657 h, err := userIdSignatureV3Hash(id, pub, sig.Hash) 658 if err != nil { 659 return err 660 } 661 return pk.VerifySignatureV3(h, sig) 662 } 663 664 // KeyIdString returns the public key's fingerprint in capital hex 665 // (e.g. "6C7EE1B8621CC013"). 666 func (pk *PublicKey) KeyIdString() string { 667 return fmt.Sprintf("%X", pk.Fingerprint[12:20]) 668 } 669 670 // KeyIdShortString returns the short form of public key's fingerprint 671 // in capital hex, as shown by gpg --list-keys (e.g. "621CC013"). 672 func (pk *PublicKey) KeyIdShortString() string { 673 return fmt.Sprintf("%X", pk.Fingerprint[16:20]) 674 } 675 676 // A parsedMPI is used to store the contents of a big integer, along with the 677 // bit length that was specified in the original input. This allows the MPI to 678 // be reserialized exactly. 679 type parsedMPI struct { 680 bytes []byte 681 bitLength uint16 682 } 683 684 // writeMPIs is a utility function for serializing several big integers to the 685 // given Writer. 686 func writeMPIs(w io.Writer, mpis ...parsedMPI) (err error) { 687 for _, mpi := range mpis { 688 err = writeMPI(w, mpi.bitLength, mpi.bytes) 689 if err != nil { 690 return 691 } 692 } 693 return 694 } 695 696 // BitLength returns the bit length for the given public key. 697 func (pk *PublicKey) BitLength() (bitLength uint16, err error) { 698 switch pk.PubKeyAlgo { 699 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: 700 bitLength = pk.n.bitLength 701 case PubKeyAlgoDSA: 702 bitLength = pk.p.bitLength 703 case PubKeyAlgoElGamal: 704 bitLength = pk.p.bitLength 705 default: 706 err = errors.InvalidArgumentError("bad public-key algorithm") 707 } 708 return 709 }