]>
Commit | Line | Data |
---|---|---|
1bdbdaff P |
1 | /* |
2 | * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. | |
3 | * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. | |
4 | * | |
5 | * Licensed under the Apache License 2.0 (the "License"). You may not use | |
6 | * this file except in compliance with the License. You can obtain a copy | |
7 | * in the file LICENSE in the source distribution or at | |
8 | * https://www.openssl.org/source/license.html | |
9 | */ | |
10 | ||
11 | #include <string.h> | |
12 | #include <openssl/crypto.h> | |
13 | #include <openssl/lhash.h> | |
14 | #include "internal/lhash.h" | |
15 | #include "property_lcl.h" | |
16 | ||
17 | /* | |
18 | * Property strings are a consolidation of all strings seen by the property | |
19 | * subsystem. There are two name spaces to keep property names separate from | |
20 | * property values (numeric values are not expected to be cached however). | |
21 | * They allow a rapid conversion from a string to a unique index and any | |
22 | * subsequent string comparison can be done via an integer compare. | |
23 | * | |
24 | * This implementation uses OpenSSL's standard hash table. There are more | |
25 | * space and time efficient algorithms if this becomes a bottleneck. | |
26 | */ | |
27 | ||
28 | typedef struct { | |
29 | const char *s; | |
30 | OSSL_PROPERTY_IDX idx; | |
31 | char body[1]; | |
32 | } PROPERTY_STRING; | |
33 | ||
34 | DEFINE_LHASH_OF(PROPERTY_STRING); | |
35 | typedef LHASH_OF(PROPERTY_STRING) PROP_TABLE; | |
36 | ||
37 | static PROP_TABLE *prop_names; | |
38 | static PROP_TABLE *prop_values; | |
39 | static OSSL_PROPERTY_IDX prop_name_idx = 0; | |
40 | static OSSL_PROPERTY_IDX prop_value_idx = 0; | |
41 | ||
42 | static unsigned long property_hash(const PROPERTY_STRING *a) | |
43 | { | |
44 | return OPENSSL_LH_strhash(a->s); | |
45 | } | |
46 | ||
47 | static int property_cmp(const PROPERTY_STRING *a, const PROPERTY_STRING *b) | |
48 | { | |
49 | return strcmp(a->s, b->s); | |
50 | } | |
51 | ||
52 | static void property_free(PROPERTY_STRING *ps) | |
53 | { | |
54 | OPENSSL_free(ps); | |
55 | } | |
56 | ||
57 | static void property_table_free(PROP_TABLE **pt) | |
58 | { | |
59 | PROP_TABLE *t = *pt; | |
60 | ||
61 | if (t != NULL) { | |
62 | lh_PROPERTY_STRING_doall(t, &property_free); | |
63 | lh_PROPERTY_STRING_free(t); | |
64 | *pt = NULL; | |
65 | } | |
66 | } | |
67 | ||
68 | static PROPERTY_STRING *new_property_string(const char *s, | |
69 | OSSL_PROPERTY_IDX *pidx) | |
70 | { | |
71 | const size_t l = strlen(s); | |
72 | PROPERTY_STRING *ps = OPENSSL_malloc(sizeof(*ps) + l); | |
73 | ||
74 | if (ps != NULL) { | |
75 | memcpy(ps->body, s, l + 1); | |
76 | ps->s = ps->body; | |
77 | ps->idx = ++*pidx; | |
78 | if (ps->idx == 0) { | |
79 | OPENSSL_free(ps); | |
80 | return NULL; | |
81 | } | |
82 | } | |
83 | return ps; | |
84 | } | |
85 | ||
86 | static OSSL_PROPERTY_IDX ossl_property_string(PROP_TABLE *t, | |
87 | OSSL_PROPERTY_IDX *pidx, | |
88 | const char *s) | |
89 | { | |
90 | PROPERTY_STRING p, *ps, *ps_new; | |
91 | ||
92 | p.s = s; | |
93 | ps = lh_PROPERTY_STRING_retrieve(t, &p); | |
94 | if (ps == NULL && pidx != NULL) | |
95 | if ((ps_new = new_property_string(s, pidx)) != NULL) { | |
96 | lh_PROPERTY_STRING_insert(t, ps_new); | |
97 | if (lh_PROPERTY_STRING_error(t)) { | |
98 | property_free(ps_new); | |
99 | return 0; | |
100 | } | |
101 | ps = ps_new; | |
102 | } | |
103 | return ps != NULL ? ps->idx : 0; | |
104 | } | |
105 | ||
106 | OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create) | |
107 | { | |
108 | return ossl_property_string(prop_names, create ? &prop_name_idx : NULL, s); | |
109 | } | |
110 | ||
111 | OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create) | |
112 | { | |
113 | return ossl_property_string(prop_values, create ? &prop_value_idx : NULL, s); | |
114 | } | |
115 | ||
116 | int ossl_property_string_init(void) | |
117 | { | |
118 | prop_names = lh_PROPERTY_STRING_new(&property_hash, &property_cmp); | |
119 | if (prop_names == NULL) | |
120 | return 0; | |
121 | ||
122 | prop_values = lh_PROPERTY_STRING_new(&property_hash, &property_cmp); | |
123 | if (prop_values == NULL) | |
124 | goto err; | |
125 | return 1; | |
126 | ||
127 | err: | |
128 | ossl_property_string_cleanup(); | |
129 | return 0; | |
130 | } | |
131 | ||
132 | void ossl_property_string_cleanup(void) | |
133 | { | |
134 | property_table_free(&prop_names); | |
135 | property_table_free(&prop_values); | |
136 | prop_name_idx = prop_value_idx = 0; | |
137 | } |