github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/appengine/login/googlesignin/jwt-go/rsa_utils.go (about)

     1  package jwt
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rsa"
     6  	"crypto/x509"
     7  	"encoding/pem"
     8  	"errors"
     9  	"fmt"
    10  	"log"
    11  )
    12  
    13  var (
    14  	ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key")
    15  	ErrNotRSAPrivateKey    = errors.New("Key is not a valid RSA private key")
    16  )
    17  
    18  // Parse PEM encoded PKCS1 or PKCS8 private key
    19  func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
    20  	var err error
    21  
    22  	// Parse PEM block
    23  	var block *pem.Block
    24  	if block, _ = pem.Decode(key); block == nil {
    25  		return nil, ErrKeyMustBePEMEncoded
    26  	}
    27  
    28  	var parsedKey interface{}
    29  	if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
    30  		if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
    31  			return nil, err
    32  		}
    33  	}
    34  
    35  	var pkey *rsa.PrivateKey
    36  	var ok bool
    37  	if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {
    38  		return nil, ErrNotRSAPrivateKey
    39  	}
    40  
    41  	return pkey, nil
    42  }
    43  
    44  // https://developers.google.com/identity/sign-in/web/backend-auth
    45  //  https://www.googleapis.com/oauth2/v1/certs
    46  var MappingToPEM = map[string]string{
    47  	"070e3470adad2a897c648ee3d320f693cde6a1b0": "-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIIMY08VrIzxEwwDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE\nAxMrZmVkZXJhdGVkLXNpZ25vbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTAe\nFw0xNTEwMDkwNDEzMzRaFw0xNTEwMTAxNzEzMzRaMDYxNDAyBgNVBAMTK2ZlZGVy\nYXRlZC1zaWdub24uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVt1f6T91xxQrX5DOcFzPJqjClUbAE2ntO\nLWv2zVJU75ZDEFm/HR1AoK54+Z4xsDJr7EtEwcVZcIBZ8TwemvljuF6e0bGSjw+6\nzLqt3RtjB9WY19jcvsdCActYwBHe2Po0AHgeBjlQA3w5begTsG4TMQFPKXd4hWwE\nfIF0HfDsjoSiEnpADM/rtap/HjRUpRs4g5VMUl19yuIRil11PkeKrW7speK6d4wz\neTvuscNt1Rz75Mk19YSG4ZxbbaizWr0JtwpLgj9j2XdoD/VF+3s69oZaaV90IeQP\nIKJ7iPlJaaAYValxCrwLirjVtMvWEuRIekeMbZDNFjRSQ2uFS42vAgMBAAGjODA2\nMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsG\nAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQC+VrTMe6i8rkY96dNU9rZOuqZ2Yx17\nGqWFeZFMzMzIlFXL36ZBm4HYhjLthloQ9D2E5X29iu/n6e86PEm8mccaqpxX1C0J\nruZlJhFXEZskv4xvJ8z4padjS/NaJURHWztiqYOVwXW78TtsFHRM6cUmvRXXxQMi\nChWxLY2aVqpo7IdyftsWDrojTw34yg8W8uHRSXS75ciPbacQOw8uWzk1v4toNezN\n8qGYl5TR8Yz/fYMg6oSS83OAHi9wjOuOUaDS2vr7HJGbGFdmr7iqq9qsGQ5pMJS1\nOY4FATPPraWwettGxb9jo2vg7ZxYwvEwZnocgZPfVfawWvMrWo83iWV5\n-----END CERTIFICATE-----\n",
    48  	"3b386b69a9815a1651155a3427c6ce7c84fbfbb8": "-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIIH0lHQ9hi80AwDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE\nAxMrZmVkZXJhdGVkLXNpZ25vbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTAe\nFw0xNTEwMDcwNDQzMzRaFw0xNTEwMDgxNzQzMzRaMDYxNDAyBgNVBAMTK2ZlZGVy\nYXRlZC1zaWdub24uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBjExXqZM9+E7Qm3gn5PY+eYQql1oBv/+x\n4QsPTIaH+KQK7gyj7FQmdb82+tiCmj68yO9RQEs+gspLJSJvUainKToQJFRDvh7q\nXn3K4YOdLq1L9JwDyrjEIurPP0K4gX27gNF5FgefeBB4zBBUS0V1aPUOwePsbV6f\n7A4LM7MMssuN5/xg+S5gM5VLK/3G8yzS2MPkhR/jzTCuHCuqWM4BjNvG1OVjvqlF\ntzKwmu+q3KQWpmddSqAua48sMycNA5pNjpFt3tlR5dlgQUodlQDBmFOqOgHs5Ra7\nWUQ4/v9sjfufWxj/B87EeeSImd78DnsQvRXtMi8EJ23UywADbI0NAgMBAAGjODA2\nMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsG\nAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQBE2vRKCM1PfUqVEId4U7sell6gUTO8\nYPqOOZSb7IDki/rtPFDBi83fpO7nYT1KF++fz2d92dRtQotJaJs7WMGwq9AvgbCK\nOwG5kK3avNXKDR2VjZ5CYqJdT2N/mvYEh/1rRC9n35Xhg2c6lyr9gLCBplvOvKYi\nnl6GpM9UhE6qdSNmtj8WMSJdCMCoarIGUkuD0Q5Hw4mLgmnm0B55KCCcH9WfpbM8\ngXlCG0uQY4RcjtGXVT0jbR1++kqpSuzLTVl3Ydm9hURtkE7GsVcZxffBA9QN41D+\nb2p8whvcgrLQEt5gj6DdQx1zW2jUtimkr3xv4y9ndPmeaLFIgfQYO6md\n-----END CERTIFICATE-----\n",
    49  	"9015759ea37707cb6d325cca00e6299231b7f72f": "-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIIF6DTc3dfzIQwDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE\nAxMrZmVkZXJhdGVkLXNpZ25vbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTAe\nFw0xNTEwMDgwNDI4MzRaFw0xNTEwMDkxNzI4MzRaMDYxNDAyBgNVBAMTK2ZlZGVy\nYXRlZC1zaWdub24uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDerjHE9ShSDpOToUhwphHqgCCCUaFmqv4H\npanLmHicb/GRvYbzgnTx3fhVERTziiajR05kh0/6cZuzmKaqiDKJV4EMUI3LzbNc\nR3b38q2ZNhUjUR2xBoLnp1qN2+HI5fDrh3DpWjv5h8MAz+w8w94ZzfQlsONd3iCg\n3GUD4XXX0A88aqEj9ioW5CXXiMz644iopu3uWecvYKf2oyf0knR/S+EHz449k9Gd\n2Ao9Bz3kwWhGi1/Dj5Zbn1sbxY9pCVGLfZHyFHER6yZSe1XzFxCnyI3UZIl/kmM8\nIeAIf5fcrsHKzVHnVD2gUIRbtfmIwOmwfkWJ8j8VS+ctg3TWIIzhAgMBAAGjODA2\nMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsG\nAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQCewKRGFViLC94Dnhc9YUZWE1oatp2F\nw1El7EHMbSR1fTWo7hcZIdiPc1bewHrkW+mMHnKx8zYKiFagRk6sZdoGvBHeu2Oz\nLWtcnzEdj51z8/piLDfkZD3FZaCZlF66NnekGs1vq+2zmJRBGRSCuM5X18/OQKkz\nkyKIM36OQXzlpsMCoep3BRyKUgBUV6zCMOIpsVNzOj2sPIxZGguNYUMk899eDrFe\nEdvL1K92XOJPtteQW2a7yD2tA5ln3wdBbLkiZqpumGa55SobCB0tXCMUlhlcgAXv\n5ChR4JyWZ88gHRXiRpxR+9rYVnSChMw8I8suonfTus/CqLc152FGMory\n-----END CERTIFICATE-----\n",
    50  }
    51  
    52  var ErrPEMMappingObsolete = fmt.Errorf("mapping to PEM key is obsolete")
    53  
    54  // Parse PEM encoded PKCS1 or PKCS8 public key
    55  func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
    56  	var err error
    57  
    58  	// Parse PEM block
    59  	var block *pem.Block
    60  
    61  	if !bytes.Contains(key, []byte("BEGIN CERTIFICATE")) {
    62  		skey := string(key)
    63  		if sval, ok := MappingToPEM[skey]; ok {
    64  			key = []byte(sval)
    65  			log.Printf("\n=====================\nreplaced %v with %v", len(skey), len(MappingToPEM[skey]))
    66  			log.Printf("%v", skey)
    67  		} else {
    68  			return nil, ErrPEMMappingObsolete
    69  		}
    70  	}
    71  
    72  	if block, _ = pem.Decode(key); block == nil {
    73  		log.Println("PEM_decoding failed")
    74  		return nil, ErrKeyMustBePEMEncoded
    75  	}
    76  
    77  	// Parse the key
    78  	var parsedKey interface{}
    79  	if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
    80  		if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
    81  			parsedKey = cert.PublicKey
    82  		} else {
    83  			return nil, err
    84  		}
    85  	}
    86  
    87  	var pkey *rsa.PublicKey
    88  	var ok bool
    89  	if pkey, ok = parsedKey.(*rsa.PublicKey); !ok {
    90  		return nil, ErrNotRSAPrivateKey
    91  	}
    92  
    93  	return pkey, nil
    94  }