nuts-foundation/nuts-node

View on GitHub
crypto/interface.go

Summary

Maintainability
A
0 mins
Test Coverage
/*
 * Nuts node
 * Copyright (C) 2021 Nuts community
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package crypto

import (
    "context"
    "crypto"
    "errors"
    "github.com/nuts-foundation/nuts-node/crypto/dpop"
)

// ErrPrivateKeyNotFound is returned when the private key doesn't exist
var ErrPrivateKeyNotFound = errors.New("private key not found")

// KIDNamingFunc is a function passed to New() which generates the kid for the pub/priv key
type KIDNamingFunc func(key crypto.PublicKey) (string, error)

// KeyCreator is the interface for creating key pairs.
type KeyCreator interface {
    // New generates a keypair and returns a Key. The context is used to pass audit information.
    // The KIDNamingFunc will provide the kid.
    New(ctx context.Context, namingFunc KIDNamingFunc) (Key, error)
}

// KeyResolver is the interface for resolving keys.
type KeyResolver interface {
    // Exists returns if the specified private key exists.
    // If an error occurs, false is also returned
    Exists(ctx context.Context, kid string) (bool, error)
    // Resolve returns a Key for the given KID. ErrPrivateKeyNotFound is returned for an unknown KID.
    Resolve(ctx context.Context, kid string) (Key, error)
    // List returns the KIDs of the private keys that are present in the KeyStore.
    List(ctx context.Context) []string
}

// KeyStore defines the functions for working with private keys.
type KeyStore interface {
    Decrypter
    JsonWebEncryptor
    KeyCreator
    KeyResolver
    JWTSigner

    // Delete removes the private key with the given KID from the KeyStore.
    Delete(ctx context.Context, kid string) error
}

// Decrypter is the interface to support decryption
type Decrypter interface {
    // Decrypt decrypts the `cipherText` with key `kid`
    // The context is used to pass audit information.
    // Note: decryption isn't audit logged, because:
    // - it involved very deep context passing,
    // - it's called by the system itself, not triggered by a user.
    // - to be removed in near future when we switch to multi-chains, which eliminates private TXs and thus encryption altogether.
    Decrypt(ctx context.Context, kid string, ciphertext []byte) ([]byte, error)
}

// JWTSigner is the interface used to sign authorization tokens.
type JWTSigner interface {
    // SignJWT creates a signed JWT using the indicated key and map of claims and additional headers.
    // The key can be its KID (key ID) or an instance of Key, the context is used to pass audit information.
    // The headers can be used to add/override headers in the JWT.
    // Returns ErrPrivateKeyNotFound when the private key is not present.
    SignJWT(ctx context.Context, claims map[string]interface{}, headers map[string]interface{}, key interface{}) (string, error)
    // SignJWS creates a signed JWS using the indicated key and map of headers and payload as bytes.
    // The detached boolean indicates if the body needs to be excluded from the response (detached mode).
    // The key can be its KID (key ID) or an instance of Key,
    // context is used to pass audit information.
    // Returns ErrPrivateKeyNotFound when the private key is not present.
    SignJWS(ctx context.Context, payload []byte, headers map[string]interface{}, key interface{}, detached bool) (string, error)
    // SignDPoP signs a DPoP token for the given kid.
    // It adds the requested key as jwk header to the DPoP token.
    SignDPoP(ctx context.Context, token dpop.DPoP, kid string) (string, error)
}

// JsonWebEncryptor is the interface used to encrypt and decrypt JWE messages.
type JsonWebEncryptor interface {
    // EncryptJWE encrypts a payload as bytes into a JWE message with the given key and kid.
    // The publicKey must be a public key
    // The kid must be the KeyID and will be placed in the header, if not set.
    EncryptJWE(ctx context.Context, payload []byte, headers map[string]interface{}, publicKey interface{}) (string, error)

    // DecryptJWE decrypts a message as bytes into a decrypted body and headers.
    // The corresponding private key must be located in the KeyID (kid) header.
    DecryptJWE(ctx context.Context, message string) (body []byte, headers map[string]interface{}, err error)
}

// Key is a helper interface that describes a private key in the crypto module, specifying its KID and public part.
type Key interface {
    // KID returns the unique ID for this key.
    KID() string
    // Public returns the public key.
    Public() crypto.PublicKey
}

// exportableKey is a Key that contains the private key itself and thus is exportable.
// Should only be used for select purposes (e.g. ephemeral keys).
type exportableKey interface {
    Key
    // Signer returns the private key.
    Signer() crypto.Signer
}