aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/aws-c-io/source/pkcs11_private.h
blob: 8eeca4604fa3a135747ef50c7d95d9f24792b1c5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#ifndef AWS_IO_PKCS11_PRIVATE_H
#define AWS_IO_PKCS11_PRIVATE_H

/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
#include <aws/io/io.h>

/* These defines must exist before the official PKCS#11 headers are included */
#define CK_PTR *
#define NULL_PTR 0
#define CK_DEFINE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType(CK_PTR name)
#define CK_CALLBACK_FUNCTION(returnType, name) returnType(CK_PTR name)
#include "pkcs11/v2.40/pkcs11.h"

/**
 * pkcs11_private.h
 * This file declares symbols that are private to aws-c-io but need to be
 * accessed from multiple .c files.
 *
 * NOTE: Not putting this file under `include/private/...` like we usually
 * do with private headers because it breaks aws-crt-swift. Swift was trying
 * to compile each file under include/, but the official PKCS#11 header files
 * are too weird break it.
 */

struct aws_pkcs11_lib;
struct aws_string;

enum aws_tls_hash_algorithm {
    AWS_TLS_HASH_UNKNOWN = -1,
    AWS_TLS_HASH_SHA1,
    AWS_TLS_HASH_SHA224,
    AWS_TLS_HASH_SHA256,
    AWS_TLS_HASH_SHA384,
    AWS_TLS_HASH_SHA512,
};

enum aws_tls_signature_algorithm {
    AWS_TLS_SIGNATURE_UNKNOWN = -1,
    AWS_TLS_SIGNATURE_RSA,
    AWS_TLS_SIGNATURE_ECDSA,
};

AWS_EXTERN_C_BEGIN

/**
 * Return c-string for PKCS#11 CKR_* constant.
 * For use in tests only.
 */
AWS_IO_API
const char *aws_pkcs11_ckr_str(CK_RV rv);

/**
 * Return the raw function list.
 * For use in tests only.
 */
AWS_IO_API
CK_FUNCTION_LIST *aws_pkcs11_lib_get_function_list(struct aws_pkcs11_lib *pkcs11_lib);

/**
 * Find the slot that meets all criteria:
 * - has a token
 * - if match_slot_id is non-null, then slot IDs must match
 * - if match_token_label is non-null, then labels must match
 * The function fails unless it finds exactly one slot meeting all criteria.
 */
AWS_IO_API
int aws_pkcs11_lib_find_slot_with_token(
    struct aws_pkcs11_lib *pkcs11_lib,
    const uint64_t *match_slot_id,
    const struct aws_string *match_token_label,
    CK_SLOT_ID *out_slot_id);

AWS_IO_API
int aws_pkcs11_lib_open_session(
    struct aws_pkcs11_lib *pkcs11_lib,
    CK_SLOT_ID slot_id,
    CK_SESSION_HANDLE *out_session_handle);

AWS_IO_API
void aws_pkcs11_lib_close_session(struct aws_pkcs11_lib *pkcs11_lib, CK_SESSION_HANDLE session_handle);

AWS_IO_API
int aws_pkcs11_lib_login_user(
    struct aws_pkcs11_lib *pkcs11_lib,
    CK_SESSION_HANDLE session_handle,
    const struct aws_string *optional_user_pin);

/**
 * Find the object that meets all criteria:
 * - is private key
 * - if match_label is non-null, then labels must match
 * The function fails unless it finds exactly one object meeting all criteria.
 */
AWS_IO_API
int aws_pkcs11_lib_find_private_key(
    struct aws_pkcs11_lib *pkcs11_lib,
    CK_SESSION_HANDLE session_handle,
    const struct aws_string *match_label,
    CK_OBJECT_HANDLE *out_key_handle,
    CK_KEY_TYPE *out_key_type);

/**
 * Decrypt the encrypted data.
 * out_data should be passed in uninitialized.
 * If successful, out_data will be initialized and contain the recovered data.
 */
AWS_IO_API
int aws_pkcs11_lib_decrypt(
    struct aws_pkcs11_lib *pkcs11_lib,
    CK_SESSION_HANDLE session_handle,
    CK_OBJECT_HANDLE key_handle,
    CK_KEY_TYPE key_type,
    struct aws_byte_cursor encrypted_data,
    struct aws_allocator *allocator,
    struct aws_byte_buf *out_data);

/**
 * Sign a digest with the private key during TLS negotiation.
 * out_signature should be passed in uninitialized.
 * If successful, out_signature will be initialized and contain the signature.
 */
AWS_IO_API
int aws_pkcs11_lib_sign(
    struct aws_pkcs11_lib *pkcs11_lib,
    CK_SESSION_HANDLE session_handle,
    CK_OBJECT_HANDLE key_handle,
    CK_KEY_TYPE key_type,
    struct aws_byte_cursor digest_data,
    struct aws_allocator *allocator,
    enum aws_tls_hash_algorithm digest_alg,
    enum aws_tls_signature_algorithm signature_alg,
    struct aws_byte_buf *out_signature);

/**
 * Get the DER encoded DigestInfo value to be prefixed to the hash, used for RSA signing
 * See https://tools.ietf.org/html/rfc3447#page-43
 */
AWS_IO_API
int aws_get_prefix_to_rsa_sig(enum aws_tls_hash_algorithm digest_alg, struct aws_byte_cursor *out_prefix);

/**
 * ASN.1 DER encode a big unsigned integer. Note that the source integer may be zero padded. It may also have
 * most significant bit set. The encoded format is canonical and unambiguous - that is, most significant
 * bit is never set.
 */
AWS_IO_API
int aws_pkcs11_asn1_enc_ubigint(struct aws_byte_buf *const buffer, struct aws_byte_cursor bigint);

/**
 * Given enum, return string like: AWS_TLS_HASH_SHA256 -> "SHA256"
 */
AWS_IO_API
const char *aws_tls_hash_algorithm_str(enum aws_tls_hash_algorithm hash);

/**
 * Given enum, return string like: AWS_TLS_SIGNATURE_RSA -> "RSA"
 */
AWS_IO_API
const char *aws_tls_signature_algorithm_str(enum aws_tls_signature_algorithm signature);

AWS_EXTERN_C_END
#endif /* AWS_IO_PKCS11_PRIVATE_H */