Skip to content

Commit

Permalink
Split authentication policies into public definition, private impleme…
Browse files Browse the repository at this point in the history
…ntation (#3536)
  • Loading branch information
eddyashton authored Feb 10, 2022
1 parent 7ef8cec commit 26b8b30
Show file tree
Hide file tree
Showing 30 changed files with 771 additions and 626 deletions.
5 changes: 5 additions & 0 deletions cmake/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@ set(CCF_ENDPOINTS_SOURCES
${CCF_DIR}/src/endpoints/endpoint_registry.cpp
${CCF_DIR}/src/endpoints/base_endpoint_registry.cpp
${CCF_DIR}/src/endpoints/common_endpoint_registry.cpp
${CCF_DIR}/src/endpoints/authentication/authentication_types.cpp
${CCF_DIR}/src/endpoints/authentication/cert_auth.cpp
${CCF_DIR}/src/endpoints/authentication/empty_auth.cpp
${CCF_DIR}/src/endpoints/authentication/jwt_auth.cpp
${CCF_DIR}/src/endpoints/authentication/sig_auth.cpp
${CCF_DIR}/src/enclave/enclave_time.cpp
)

Expand Down
12 changes: 9 additions & 3 deletions include/ccf/common_auth_policies.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// Licensed under the Apache 2.0 License.
#pragma once

#include "http/authentication/cert_auth.h"
#include "http/authentication/jwt_auth.h"
#include "http/authentication/sig_auth.h"
#include "ccf/endpoints/authentication/cert_auth.h"
#include "ccf/endpoints/authentication/empty_auth.h"
#include "ccf/endpoints/authentication/jwt_auth.h"
#include "ccf/endpoints/authentication/sig_auth.h"

#include <memory>

Expand All @@ -19,23 +20,28 @@ namespace ccf
/** Perform no authentication */
static std::shared_ptr<EmptyAuthnPolicy> empty_auth_policy =
std::make_shared<EmptyAuthnPolicy>();

/** Authenticate using TLS session identity, and @c public:ccf.gov.users.certs
* table */
static std::shared_ptr<UserCertAuthnPolicy> user_cert_auth_policy =
std::make_shared<UserCertAuthnPolicy>();

/** Authenticate using HTTP request signature, and
* @c public:ccf.gov.users.certs table */
static std::shared_ptr<UserSignatureAuthnPolicy> user_signature_auth_policy =
std::make_shared<UserSignatureAuthnPolicy>();

/** Authenticate using TLS session identity, and
* @c public:ccf.gov.members.certs table */
static std::shared_ptr<MemberCertAuthnPolicy> member_cert_auth_policy =
std::make_shared<MemberCertAuthnPolicy>();

/** Authenticate using HTTP request signature, and
* @c public:ccf.gov.members.certs table */
static std::shared_ptr<MemberSignatureAuthnPolicy>
member_signature_auth_policy =
std::make_shared<MemberSignatureAuthnPolicy>();

/** Authenticate using JWT, validating the token using the
* @c public:ccf.gov.jwt.public_signing_key_issuer and
* @c public:ccf.gov.jwt.public_signing_keys tables */
Expand Down
25 changes: 25 additions & 0 deletions include/ccf/crypto.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the Apache 2.0 License.
#pragma once

#include "ds/json.h"

namespace crypto
{
enum class MDType
{
NONE = 0,
SHA1,
SHA256,
SHA384,
SHA512
};

DECLARE_JSON_ENUM(
MDType,
{{MDType::NONE, "NONE"},
{MDType::SHA1, "SHA1"},
{MDType::SHA256, "SHA256"},
{MDType::SHA384, "SHA384"},
{MDType::SHA512, "SHA512"}});
}
2 changes: 1 addition & 1 deletion include/ccf/endpoint_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// Licensed under the Apache 2.0 License.
#pragma once

#include "ccf/endpoints/authentication/authentication_types.h"
#include "enclave/rpc_context.h"
#include "http/authentication/authentication_types.h"

#include <functional>
#include <memory>
Expand Down
45 changes: 45 additions & 0 deletions include/ccf/endpoints/authentication/authentication_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the Apache 2.0 License.
#pragma once

#include "ccf/tx.h"

#include <memory>
#include <nlohmann/json.hpp>
#include <string>

namespace enclave
{
class RpcContext;
}

namespace ccf
{
struct AuthnIdentity
{
virtual ~AuthnIdentity() = default;
};

using OpenAPISecuritySchema = std::pair<std::string, nlohmann::json>;
static const OpenAPISecuritySchema unauthenticated_schema =
std::make_pair("", nlohmann::json());

class AuthnPolicy
{
public:
virtual ~AuthnPolicy() = default;

virtual std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
const std::shared_ptr<enclave::RpcContext>& ctx,
std::string& error_reason) = 0;

virtual void set_unauthenticated_error(
std::shared_ptr<enclave::RpcContext>& ctx, std::string&& error_reason);

virtual std::optional<OpenAPISecuritySchema> get_openapi_security_schema()
const = 0;
};

using AuthnPolicies = std::vector<std::shared_ptr<AuthnPolicy>>;
}
86 changes: 86 additions & 0 deletions include/ccf/endpoints/authentication/cert_auth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the Apache 2.0 License.
#pragma once

#include "ccf/endpoints/authentication/authentication_types.h"
#include "ccf/entity_id.h"

namespace ccf
{
namespace
{
std::optional<OpenAPISecuritySchema> get_cert_based_security_schema()
{
// There is currently no OpenAPI-compliant way to describe cert-based TLS
// auth, so this policy is not documented. This should change in
// OpenAPI3.1: https://github.com/OAI/OpenAPI-Specification/pull/1764
return std::nullopt;
}
}

struct UserCertAuthnIdentity : public AuthnIdentity
{
/** CCF user ID */
UserId user_id;
};

class UserCertAuthnPolicy : public AuthnPolicy
{
public:
static constexpr auto SECURITY_SCHEME_NAME = "user_cert";

std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
const std::shared_ptr<enclave::RpcContext>& ctx,
std::string& error_reason) override;

std::optional<OpenAPISecuritySchema> get_openapi_security_schema()
const override
{
return get_cert_based_security_schema();
}
};

struct MemberCertAuthnIdentity : public AuthnIdentity
{
/** CCF member ID */
MemberId member_id;
};

class MemberCertAuthnPolicy : public AuthnPolicy
{
public:
static constexpr auto SECURITY_SCHEME_NAME = "member_cert";

std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
const std::shared_ptr<enclave::RpcContext>& ctx,
std::string& error_reason) override;

std::optional<OpenAPISecuritySchema> get_openapi_security_schema()
const override
{
return get_cert_based_security_schema();
}
};

struct NodeCertAuthnIdentity : public AuthnIdentity
{
ccf::NodeId node_id;
};

class NodeCertAuthnPolicy : public AuthnPolicy
{
public:
std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
const std::shared_ptr<enclave::RpcContext>& ctx,
std::string& error_reason) override;

std::optional<OpenAPISecuritySchema> get_openapi_security_schema()
const override
{
return get_cert_based_security_schema();
}
};
}
33 changes: 33 additions & 0 deletions include/ccf/endpoints/authentication/empty_auth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the Apache 2.0 License.
#pragma once

#include "ccf/endpoints/authentication/authentication_types.h"

namespace ccf
{
// To make authentication _optional_, no-auth can be listed as one of several
// specified policies
struct EmptyAuthnIdentity : public AuthnIdentity
{};

class EmptyAuthnPolicy : public AuthnPolicy
{
public:
static constexpr auto SECURITY_SCHEME_NAME = "no_auth";

std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx&,
const std::shared_ptr<enclave::RpcContext>&,
std::string&) override;

void set_unauthenticated_error(
std::shared_ptr<enclave::RpcContext>&, std::string&&) override;

std::optional<OpenAPISecuritySchema> get_openapi_security_schema()
const override
{
return unauthenticated_schema;
}
};
}
43 changes: 43 additions & 0 deletions include/ccf/endpoints/authentication/jwt_auth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the Apache 2.0 License.
#pragma once

#include "ccf/endpoints/authentication/authentication_types.h"

namespace ccf
{
struct JwtAuthnIdentity : public AuthnIdentity
{
/** JWT key issuer, as defined in @c
* public:ccf.gov.jwt_public_signing_key_issuer */
std::string key_issuer;
/** JWT header */
nlohmann::json header;
/** JWT payload */
nlohmann::json payload;
};

class JwtAuthnPolicy : public AuthnPolicy
{
protected:
static const OpenAPISecuritySchema security_schema;

public:
static constexpr auto SECURITY_SCHEME_NAME = "jwt";

std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
const std::shared_ptr<enclave::RpcContext>& ctx,
std::string& error_reason) override;

void set_unauthenticated_error(
std::shared_ptr<enclave::RpcContext>& ctx,
std::string&& error_reason) override;

std::optional<OpenAPISecuritySchema> get_openapi_security_schema()
const override
{
return security_schema;
}
};
}
93 changes: 93 additions & 0 deletions include/ccf/endpoints/authentication/sig_auth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the Apache 2.0 License.
#pragma once

#include "ccf/endpoints/authentication/authentication_types.h"
#include "ccf/entity_id.h"
#include "ccf/service/signed_req.h"

namespace ccf
{
struct UserSignatureAuthnIdentity : public AuthnIdentity
{
/** CCF user ID */
UserId user_id;
/** User certificate, used to sign this request, described by keyId */
crypto::Pem user_cert;
/** Canonicalised request and associated signature */
SignedReq signed_request;
};

struct VerifierCache;

class UserSignatureAuthnPolicy : public AuthnPolicy
{
protected:
static const OpenAPISecuritySchema security_schema;
std::unique_ptr<VerifierCache> verifiers;

public:
static constexpr auto SECURITY_SCHEME_NAME = "user_signature";

UserSignatureAuthnPolicy();
~UserSignatureAuthnPolicy();

std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
const std::shared_ptr<enclave::RpcContext>& ctx,
std::string& error_reason) override;

void set_unauthenticated_error(
std::shared_ptr<enclave::RpcContext>& ctx,
std::string&& error_reason) override;

std::optional<OpenAPISecuritySchema> get_openapi_security_schema()
const override
{
return security_schema;
}
};

struct MemberSignatureAuthnIdentity : public AuthnIdentity
{
/** CCF member ID */
MemberId member_id;

/** Member certificate, used to sign this request, described by keyId */
crypto::Pem member_cert;

/** Canonicalised request and associated signature */
SignedReq signed_request;

/** Digest of request */
std::vector<uint8_t> request_digest;
};

class MemberSignatureAuthnPolicy : public AuthnPolicy
{
protected:
static const OpenAPISecuritySchema security_schema;
std::unique_ptr<VerifierCache> verifiers;

public:
static constexpr auto SECURITY_SCHEME_NAME = "member_signature";

MemberSignatureAuthnPolicy();
~MemberSignatureAuthnPolicy();

std::unique_ptr<AuthnIdentity> authenticate(
kv::ReadOnlyTx& tx,
const std::shared_ptr<enclave::RpcContext>& ctx,
std::string& error_reason) override;

void set_unauthenticated_error(
std::shared_ptr<enclave::RpcContext>& ctx,
std::string&& error_reason) override;

std::optional<OpenAPISecuritySchema> get_openapi_security_schema()
const override
{
return security_schema;
}
};
}
Loading

0 comments on commit 26b8b30

Please sign in to comment.