aboutsummaryrefslogtreecommitdiffstats
path: root/libparc/parc/security/parc_CryptoCache.c
blob: 07caaed7d40b8d8d2226cb5c432def99d8ded466 (plain)
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
/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @header parc_CryptoCache.c
 * <#Abstract#>
 *
 *     <#Discussion#>
 *
 *
 * Example:
 * @code
 * <#example#>
 * @endcode
 */
/*
 * This should be updated to make a reference counted copy of PARCKey and store that (along with its KeyId)
 * instead of using a direct copy of the user data.  That way, there's no issues about destroying the entry
 * but the user retaining a (now invalid) reference to it.
 *
 */

#include <config.h>
#include <stdio.h>
#include <string.h>

#include <parc/assert/parc_Assert.h>

#include <parc/algol/parc_Memory.h>
#include <parc/security/parc_CryptoCache.h>
#include <parc/algol/parc_HashCodeTable.h>

struct parc_crypto_cache {
    PARCHashCodeTable *keyid_table;
};

// =====================================================================
// Translations from void* to typed pointer for use in HashCodeTable

static bool
_keyidEquals(const void *ptrA, const void *ptrB)
{
    return parcKeyId_Equals((const PARCKeyId *) ptrA, (const PARCKeyId *) ptrB);
}

static void
_dataDestroy(void **voidPtr)
{
    PARCKey **keyPtr = (PARCKey **) voidPtr;
    parcKey_Release(keyPtr);
}

// =====================================================================

PARCCryptoCache *
parcCryptoCache_Create()
{
    PARCCryptoCache *cache = parcMemory_AllocateAndClear(sizeof(PARCCryptoCache));
    parcAssertNotNull(cache, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(PARCCryptoCache));

    // KeyIdDestroyer is NULL because we get the keyid out of the key, and it will be destroyed
    // when the key is destroyed.
    cache->keyid_table = parcHashCodeTable_Create(_keyidEquals, parcKeyId_HashCodeFromVoid, NULL, _dataDestroy);

    return cache;
}

/**
 * Destroys the cache and all internal buffers.
 *
 * Example:
 * @code
 * <#example#>
 * @endcode
 */
void
parcCryptoCache_Destroy(PARCCryptoCache **cryptoCachePtr)
{
    parcAssertNotNull(cryptoCachePtr, "Parameter must be non-null double pointer");
    parcAssertNotNull(*cryptoCachePtr, "Parameter must dereference to non-null pointer");

    PARCCryptoCache *cache = *cryptoCachePtr;
    parcHashCodeTable_Destroy(&cache->keyid_table);
    parcMemory_Deallocate((void **) cryptoCachePtr);
    *cryptoCachePtr = NULL;
}

/**
 * Adds the specified key to the keycache.
 *
 * Parameters must be non-null
 * Returns true if added or false if keyid alredy existed and was a different than <code>key</code>
 *
 * Example:
 * @code
 * <#example#>
 * @endcode
 */
bool
parcCryptoCache_AddKey(PARCCryptoCache *cache, PARCKey *original_key)
{
    parcAssertNotNull(cache, "Parameter cache must be non-null");
    parcAssertNotNull(original_key, "Parameter key must be non-null");

    PARCKey *key = parcKey_Copy(original_key);
    PARCKeyId *keyid = parcKey_GetKeyId(key);

    return parcHashCodeTable_Add(cache->keyid_table, keyid, key);
}

/**
 * Fetches the Key.  The user must node modify or destroy the key.
 *
 * Returns NULL if the keyid is not found.
 *
 * Example:
 * @code
 * <#example#>
 * @endcode
 */
const PARCKey *
parcCryptoCache_GetKey(PARCCryptoCache *cache, const PARCKeyId *keyid)
{
    parcAssertNotNull(cache, "Parameter cache must be non-null");
    parcAssertNotNull(keyid, "Parameter keyid must be non-null");

    return parcHashCodeTable_Get(cache->keyid_table, keyid);
}

/**
 * Removes the keyid and key.  The internal buffers are destroyed.
 *
 * Example:
 * @code
 * <#example#>
 * @endcode
 */
void
parcCryptoCache_RemoveKey(PARCCryptoCache *cache, const PARCKeyId *keyid)
{
    parcAssertNotNull(cache, "Parameter cache must be non-null");
    parcAssertNotNull(keyid, "Parameter keyid must be non-null");

    parcHashCodeTable_Del(cache->keyid_table, keyid);
}