1
0
mirror of https://github.com/lfkeitel/docker-registry-auth.git synced 2025-04-19 00:24:02 +03:00
Lee Keitel 8d2535d179 First working server
All permissions are honored, hashed passwords can be used,
everything works and most of it is tested.
2017-03-15 16:36:45 -05:00

90 lines
1.9 KiB
Go

package dockerauth
import (
"bytes"
"crypto"
"crypto/rsa"
"crypto/x509"
"encoding/base32"
"encoding/pem"
"errors"
"io/ioutil"
"strings"
)
var (
privKey *rsa.PrivateKey
keyID string
ErrKeyMustBePEMEncoded = errors.New("invalid key: Key must be PEM encoded PKCS1 or PKCS8 private key")
ErrNotRSAPrivateKey = errors.New("key is not a valid RSA private key")
)
func getPrivateKey() (*rsa.PrivateKey, error) {
if privKey != nil {
return privKey, nil
}
bytes, err := ioutil.ReadFile(config.Registry.Auth.Key)
if err != nil {
return nil, err
}
rsaPrivate, err := parseRSAPrivateKeyFromPEM(bytes)
if err != nil {
return nil, err
}
privKey = rsaPrivate
return privKey, nil
}
// parseRSAPrivateKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 private key.
func parseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
var err error
// Parse PEM block
var block *pem.Block
if block, _ = pem.Decode(key); block == nil {
return nil, ErrKeyMustBePEMEncoded
}
var parsedKey interface{}
if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
return nil, err
}
}
var pkey *rsa.PrivateKey
var ok bool
if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {
return nil, ErrNotRSAPrivateKey
}
return pkey, nil
}
func getRSAKeyID(key *rsa.PrivateKey) string {
if keyID == "" { // Only generate the key if needed
derBytes, err := x509.MarshalPKIXPublicKey(key.Public())
if err != nil {
return ""
}
hasher := crypto.SHA256.New()
hasher.Write(derBytes)
s := strings.TrimRight(base32.StdEncoding.EncodeToString(hasher.Sum(nil)[:30]), "=")
var buf bytes.Buffer
var i int
for i = 0; i < len(s)/4-1; i++ {
start := i * 4
end := start + 4
buf.WriteString(s[start:end] + ":")
}
buf.WriteString(s[i*4:])
keyID = buf.String()
}
return keyID
}