github.com/xmidt-org/webpa-common@v1.11.9/secure/key/parser.go (about) 1 package key 2 3 import ( 4 "crypto/rsa" 5 "crypto/x509" 6 "encoding/pem" 7 "errors" 8 ) 9 10 var ( 11 ErrorPEMRequired = errors.New("Keys must be PEM-encoded") 12 ErrorUnsupportedPrivateKeyFormat = errors.New("Private keys must be in PKCS1 or PKCS8 format") 13 ErrorNotRSAPrivateKey = errors.New("Only RSA private keys are supported") 14 ErrorNotRSAPublicKey = errors.New("Only RSA public keys or certificates are suppored") 15 ) 16 17 // Parser parses a chunk of bytes into a Pair. Parser implementations must 18 // always be safe for concurrent access. 19 type Parser interface { 20 // Parse examines data to produce a Pair. If the returned error is not nil, 21 // the Pair will always be nil. This method is responsible for dealing with 22 // any required decoding, such as PEM or DER. 23 ParseKey(Purpose, []byte) (Pair, error) 24 } 25 26 // defaultParser is the internal default Parser implementation 27 type defaultParser int 28 29 func (p defaultParser) String() string { 30 return "defaultParser" 31 } 32 33 func (p defaultParser) parseRSAPrivateKey(purpose Purpose, decoded []byte) (Pair, error) { 34 var ( 35 parsedKey interface{} 36 err error 37 ) 38 39 if parsedKey, err = x509.ParsePKCS1PrivateKey(decoded); err != nil { 40 if parsedKey, err = x509.ParsePKCS8PrivateKey(decoded); err != nil { 41 return nil, ErrorUnsupportedPrivateKeyFormat 42 } 43 } 44 45 privateKey, ok := parsedKey.(*rsa.PrivateKey) 46 if !ok { 47 return nil, ErrorNotRSAPrivateKey 48 } 49 50 return &rsaPair{ 51 purpose: purpose, 52 public: privateKey.Public(), 53 private: privateKey, 54 }, nil 55 } 56 57 func (p defaultParser) parseRSAPublicKey(purpose Purpose, decoded []byte) (Pair, error) { 58 var ( 59 parsedKey interface{} 60 err error 61 ) 62 63 if parsedKey, err = x509.ParsePKIXPublicKey(decoded); err != nil { 64 return nil, err 65 } 66 67 publicKey, ok := parsedKey.(*rsa.PublicKey) 68 if !ok { 69 return nil, ErrorNotRSAPublicKey 70 } 71 72 return &rsaPair{ 73 purpose: purpose, 74 public: publicKey, 75 private: nil, 76 }, nil 77 } 78 79 func (p defaultParser) ParseKey(purpose Purpose, data []byte) (Pair, error) { 80 block, _ := pem.Decode(data) 81 if block == nil { 82 return nil, ErrorPEMRequired 83 } 84 85 if purpose.RequiresPrivateKey() { 86 return p.parseRSAPrivateKey(purpose, block.Bytes) 87 } else { 88 return p.parseRSAPublicKey(purpose, block.Bytes) 89 } 90 } 91 92 // DefaultParser is the global, singleton default parser. All keys submitted to 93 // this parser must be PEM-encoded. 94 var DefaultParser Parser = defaultParser(0)