func getRSAPubKey(key data.PublicKey) (crypto.PublicKey, error) { algorithm := key.Algorithm() var pubKey crypto.PublicKey switch algorithm { case data.RSAx509Key: pemCert, _ := pem.Decode([]byte(key.Public())) if pemCert == nil { logrus.Debugf("failed to decode PEM-encoded x509 certificate") return nil, ErrInvalid } cert, err := x509.ParseCertificate(pemCert.Bytes) if err != nil { logrus.Debugf("failed to parse x509 certificate: %s\n", err) return nil, ErrInvalid } pubKey = cert.PublicKey case data.RSAKey: var err error pubKey, err = x509.ParsePKIXPublicKey(key.Public()) if err != nil { logrus.Debugf("failed to parse public key: %s\n", err) return nil, ErrInvalid } default: // only accept RSA keys logrus.Debugf("invalid key type for RSAPSS verifier: %s", algorithm) return nil, ErrInvalidKeyType{} } return pubKey, nil }
//CreateKey returns a PublicKey created using KeyManagementServer's SigningService func (s *KeyManagementServer) CreateKey(ctx context.Context, req *pb.CreateKeyRequest) (*pb.PublicKey, error) { service := s.CryptoServices[req.Algorithm] logger := ctxu.GetLogger(ctx) if service == nil { logger.Error("CreateKey: unsupported algorithm: ", req.Algorithm) return nil, fmt.Errorf("algorithm %s not supported for create key", req.Algorithm) } var tufKey data.PublicKey var err error tufKey, err = service.Create(req.Role, req.Gun, req.Algorithm) if err != nil { logger.Error("CreateKey: failed to create key: ", err) return nil, grpc.Errorf(codes.Internal, "Key creation failed") } logger.Info("CreateKey: Created KeyID ", tufKey.ID()) return &pb.PublicKey{ KeyInfo: &pb.KeyInfo{ KeyID: &pb.KeyID{ID: tufKey.ID()}, Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm()}, }, PublicKey: tufKey.Public(), }, nil }
// Verify checks that an ed25519 signature is valid func (v Ed25519Verifier) Verify(key data.PublicKey, sig []byte, msg []byte) error { if key.Algorithm() != data.ED25519Key { return ErrInvalidKeyType{} } var sigBytes [ed25519.SignatureSize]byte if len(sig) != ed25519.SignatureSize { logrus.Debugf("signature length is incorrect, must be %d, was %d.", ed25519.SignatureSize, len(sig)) return ErrInvalid } copy(sigBytes[:], sig) var keyBytes [ed25519.PublicKeySize]byte pub := key.Public() if len(pub) != ed25519.PublicKeySize { logrus.Errorf("public key is incorrect size, must be %d, was %d.", ed25519.PublicKeySize, len(pub)) return ErrInvalidKeyLength{msg: fmt.Sprintf("ed25519 public key must be %d bytes.", ed25519.PublicKeySize)} } n := copy(keyBytes[:], key.Public()) if n < ed25519.PublicKeySize { logrus.Errorf("failed to copy the key, must have %d bytes, copied %d bytes.", ed25519.PublicKeySize, n) return ErrInvalid } if !ed25519.Verify(&keyBytes, msg, &sigBytes) { logrus.Debugf("failed ed25519 verification") return ErrInvalid } return nil }
func (r *NotaryRepository) initializeRoles(rootKeys []data.PublicKey, localRoles, remoteRoles []string) ( root, targets, snapshot, timestamp data.BaseRole, err error) { root = data.NewBaseRole( data.CanonicalRootRole, notary.MinThreshold, rootKeys..., ) // we want to create all the local keys first so we don't have to // make unnecessary network calls for _, role := range localRoles { // This is currently hardcoding the keys to ECDSA. var key data.PublicKey key, err = r.CryptoService.Create(role, r.gun, data.ECDSAKey) if err != nil { return } switch role { case data.CanonicalSnapshotRole: snapshot = data.NewBaseRole( role, notary.MinThreshold, key, ) case data.CanonicalTargetsRole: targets = data.NewBaseRole( role, notary.MinThreshold, key, ) } } for _, role := range remoteRoles { // This key is generated by the remote server. var key data.PublicKey key, err = getRemoteKey(r.baseURL, r.gun, role, r.roundTrip) if err != nil { return } logrus.Debugf("got remote %s %s key with keyID: %s", role, key.Algorithm(), key.ID()) switch role { case data.CanonicalSnapshotRole: snapshot = data.NewBaseRole( role, notary.MinThreshold, key, ) case data.CanonicalTimestampRole: timestamp = data.NewBaseRole( role, notary.MinThreshold, key, ) } } return root, targets, snapshot, timestamp, nil }
// CanonicalKeyID returns the ID of the public bytes version of a TUF key. // On regular RSA/ECDSA TUF keys, this is just the key ID. On X509 RSA/ECDSA // TUF keys, this is the key ID of the public key part of the key. func CanonicalKeyID(k data.PublicKey) (string, error) { switch k.Algorithm() { case data.ECDSAx509Key, data.RSAx509Key: return trustmanager.X509PublicKeyID(k) default: return k.ID(), nil } }
// Verify does the actual check. func (v ECDSAVerifier) Verify(key data.PublicKey, sig []byte, msg []byte) error { algorithm := key.Algorithm() var pubKey crypto.PublicKey switch algorithm { case data.ECDSAx509Key: pemCert, _ := pem.Decode([]byte(key.Public())) if pemCert == nil { logrus.Debugf("failed to decode PEM-encoded x509 certificate for keyID: %s", key.ID()) logrus.Debugf("certificate bytes: %s", string(key.Public())) return ErrInvalid } cert, err := x509.ParseCertificate(pemCert.Bytes) if err != nil { logrus.Debugf("failed to parse x509 certificate: %s\n", err) return ErrInvalid } pubKey = cert.PublicKey case data.ECDSAKey: var err error pubKey, err = x509.ParsePKIXPublicKey(key.Public()) if err != nil { logrus.Debugf("Failed to parse private key for keyID: %s, %s\n", key.ID(), err) return ErrInvalid } default: // only accept ECDSA keys. logrus.Debugf("invalid key type for ECDSA verifier: %s", algorithm) return ErrInvalidKeyType{} } ecdsaPubKey, ok := pubKey.(*ecdsa.PublicKey) if !ok { logrus.Debugf("value isn't an ECDSA public key") return ErrInvalid } sigLength := len(sig) expectedOctetLength := 2 * ((ecdsaPubKey.Params().BitSize + 7) >> 3) if sigLength != expectedOctetLength { logrus.Debugf("signature had an unexpected length") return ErrInvalid } rBytes, sBytes := sig[:sigLength/2], sig[sigLength/2:] r := new(big.Int).SetBytes(rBytes) s := new(big.Int).SetBytes(sBytes) digest := sha256.Sum256(msg) if !ecdsa.Verify(ecdsaPubKey, digest[:], r, s) { logrus.Debugf("failed ECDSA signature validation") return ErrInvalid } return nil }
// X509PublicKeyID returns a public key ID as a string, given a // data.PublicKey that contains an X509 Certificate func X509PublicKeyID(certPubKey data.PublicKey) (string, error) { cert, err := LoadCertFromPEM(certPubKey.Public()) if err != nil { return "", err } pubKeyBytes, err := x509.MarshalPKIXPublicKey(cert.PublicKey) if err != nil { return "", err } var key data.PublicKey switch certPubKey.Algorithm() { case data.ECDSAx509Key: key = data.NewECDSAPublicKey(pubKeyBytes) case data.RSAx509Key: key = data.NewRSAPublicKey(pubKeyBytes) } return key.ID(), nil }
// Verify does the actual check. // N.B. We have not been able to make this work in a way that is compatible // with PyCrypto. func (v RSAPyCryptoVerifier) Verify(key data.PublicKey, sig []byte, msg []byte) error { digest := sha256.Sum256(msg) if key.Algorithm() != data.RSAKey { return ErrInvalidKeyType{} } k, _ := pem.Decode([]byte(key.Public())) if k == nil { logrus.Debugf("failed to decode PEM-encoded x509 certificate") return ErrInvalid } pub, err := x509.ParsePKIXPublicKey(k.Bytes) if err != nil { logrus.Debugf("failed to parse public key: %s\n", err) return ErrInvalid } return verifyPSS(pub, digest[:], sig) }
// X509PublicKeyID returns a public key ID as a string, given a // data.PublicKey that contains an X509 Certificate func X509PublicKeyID(certPubKey data.PublicKey) (string, error) { // Note that this only loads the first certificate from the public key cert, err := LoadCertFromPEM(certPubKey.Public()) if err != nil { return "", err } pubKeyBytes, err := x509.MarshalPKIXPublicKey(cert.PublicKey) if err != nil { return "", err } var key data.PublicKey switch certPubKey.Algorithm() { case data.ECDSAx509Key: key = data.NewECDSAPublicKey(pubKeyBytes) case data.RSAx509Key: key = data.NewRSAPublicKey(pubKeyBytes) } return key.ID(), nil }