File: database_schema.cpp

package info (click to toggle)
xca 2.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 8,328 kB
  • sloc: cpp: 30,584; sh: 341; xml: 74; makefile: 56; python: 34
file content (320 lines) | stat: -rw-r--r-- 12,588 bytes parent folder | download
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/* The "32bit hash" in public_keys, x509super, requests, certs and crls
 * is used to quickly find items in the DB by reference.
 * It consists of the first 4 bytes of a SHA1 hash.
 * Collisions are of course possible.
 *
 * All binaries are stored Base64 encoded in a column of type
 * ' B64_BLOB ' It is defined here as 'TEXT' which is huge, except
 * on mysql where LONGTEXT is used.
 */

#define B64_BLOB "_B64_BLOB_"

/*
 * The B64(DER(something)) function means DER encode something
 * and then Base64 encode that.
 * So finally this is PEM without newlines, header and footer
 *
 * Dates are always stored as 'CHAR(15)' in the
 * ASN.1 Generalized time 'yyyyMMddHHmmssZ' format
 */

#define DB_DATE "CHAR(15)"

/*
 * Configuration settings from
 *  the Options dialog, window size, last export directory,
 *  default key type and size,
 *  table column (position, sort order, visibility)
 */

	schemas[0]
<< "CREATE TABLE settings ("
	"key_ CHAR(20) UNIQUE, "        // mySql does not like 'key' or 'option"
	"value " B64_BLOB ")"
<< "INSERT INTO settings (key_, value) VALUES ('schema', '" INITIAL_SCHEMA_VERSION "')"

/*
 * All items (keys, tokens, requests, certs, crls, templates)
 * are stored here with the primary key and some common data
 * The other tables containing the details reference the 'id'
 * as FOREIGN KEY.
 */
<< "CREATE TABLE items("
	"id INTEGER PRIMARY KEY, "
	"name VARCHAR(128), "                // Internal name of the item
	"type INTEGER, "                // enum pki_type
	"source INTEGER, "                // enum pki_source
	"date " DB_DATE ", "                // Time of insertion (creation/import)
	"comment VARCHAR(2048), "
	"stamp INTEGER NOT NULL DEFAULT 0, " // indicate concurrent access
	"del SMALLINT NOT NULL DEFAULT 0)"

/*
 * Storage of public keys. Private keys and tokens also store
 * their public part here.
 */
<< "CREATE TABLE public_keys ("
	"item INTEGER, "                // reference to items(id)
	"type CHAR(4), "                // RSA DSA EC (as text)
	"hash INTEGER, "                // 32 bit hash
	"len INTEGER, "                        // key size in bits
	"\"public\" " B64_BLOB ", "        // B64(DER(public key))
	"FOREIGN KEY (item) REFERENCES items (id))"

/*
 * The private part of RSA, DSA, EC keys.
 * references to 'items' and 'public_keys'
 */
<< "CREATE TABLE private_keys ("
	"item INTEGER, "                // reference to items(id)
	"ownPass INTEGER, "                // Encrypted by DB pwd or own pwd
	"private " B64_BLOB ", "        // B64(Encrypt(DER(private key)))
	"FOREIGN KEY (item) REFERENCES items (id))"

/*
 * Smart cards or other PKCS#11 tokens
 * references to 'items' and 'public_keys'
 */
<< "CREATE TABLE tokens ("
	"item INTEGER, "                  // reference to items(id)
	"card_manufacturer VARCHAR(64), " // Card location data
	"card_serial VARCHAR(64), "          // as text
	"card_model VARCHAR(64), "
	"card_label VARCHAR(64), "
	"slot_label VARCHAR(64), "
	"object_id VARCHAR(64), "          // Unique ID on the token
	"FOREIGN KEY (item) REFERENCES items (id))"

/*
 * Encryption and hash mechanisms supported by a token
 */
<< "CREATE TABLE token_mechanism ("
	"item INTEGER, "                // reference to items(id)
	"mechanism INTEGER, "                // PKCS#11: CK_MECHANISM_TYPE
	"FOREIGN KEY (item) REFERENCES items (id))"

/*
 * An X509 Super class, consisting of a
 *  - Distinguishd name hash
 *  - Referenced key in the database
 *  - hash of the public key, used for lookups if there
 *    is no key to reference
 * used by Requests and certificates and the use-counter of keys:
 * 'SELECT from x509super WHERE pkey=?'
 */
<< "CREATE TABLE x509super ("
	"item INTEGER, "                // reference to items(id)
	"subj_hash INTEGER, "           // 32 bit hash of the Distinguished name
	"pkey INTEGER, "                // reference to the key items(id)
	"key_hash INTEGER, "            // 32 bit hash of the public key
	"FOREIGN KEY (item) REFERENCES items (id), "
	"FOREIGN KEY (pkey) REFERENCES items (id)) "

/*
 * PKCS#10 Certificate request details
 * also takes information from the 'x509super' table.
 */
<< "CREATE TABLE requests ("
	"item INTEGER, "                // reference to items(id)
	"hash INTEGER, "                // 32 bit hash of the request
	"signed INTEGER, "              // Whether it was once signed.
	"request " B64_BLOB ", "        // B64(DER(PKCS#10 request))
	"FOREIGN KEY (item) REFERENCES items (id)) "

/*
 * X509 certificate details
 * also takes information from the 'x509super' table.
 * The content of the columns: hash, iss_hash, serial, ca
 * can also be retrieved directly from the certificate, but are good
 * to lurk around for faster lookup
 */
<< "CREATE TABLE certs ("
	"item INTEGER, "                // reference to items(id)
	"hash INTEGER, "                // 32 bit hash of the cert
	"iss_hash INTEGER, "            // 32 bit hash of the issuer DN
	"serial VARCHAR(64), "          // Serial number of the certificate
	"issuer INTEGER, "              // The items(id) of the issuer or NULL
	"ca INTEGER, "                  // CA: yes / no from BasicConstraints
	"cert " B64_BLOB ", "           // B64(DER(certificate))
	"FOREIGN KEY (item) REFERENCES items (id), "
	"FOREIGN KEY (issuer) REFERENCES items (id)) "

/*
 * X509 cartificate Authority data
 */
<< "CREATE TABLE authority ("
	"item INTEGER, "                // reference to items(id)
	"template INTEGER, "            // items(id) of the default template
	"crlExpire " DB_DATE ", "       // CRL expiry date
	"crlNo INTEGER, "               // Last CRL Number
	"crlDays INTEGER, "             // CRL days until renewal
	"dnPolicy VARCHAR(1024), "      // DistinguishedName policy (UNUSED)
	"FOREIGN KEY (item) REFERENCES items (id), "
	"FOREIGN KEY (template) REFERENCES items (id)) "

/*
 * Storage of CRLs
 */
<< "CREATE TABLE crls ("
	"item INTEGER, "                // reference to items(id)
	"hash INTEGER, "                // 32 bit hash of the CRL
	"num INTEGER, "                 // Number of revoked certificates
	"iss_hash INTEGER, "            // 32 bit hash of the issuer DN
	"issuer INTEGER, "              // The items(id) of the issuer or NULL
	"crl " B64_BLOB ", "            // B64(DER(revocation list))
	"FOREIGN KEY (item) REFERENCES items (id), "
	"FOREIGN KEY (issuer) REFERENCES items (id)) "

/*
 * Revocations (serial, date, reason, issuer) used to create new
 * CRLs. 'Manage revocations'
 */
<< "CREATE TABLE revocations ("
	"caId INTEGER, "                // reference to certs(item)
	"serial VARCHAR(64), "          // Serial of the revoked certificate
	"date " DB_DATE ", "            // Time of creating the revocation
	"invaldate " DB_DATE ", "       // Time of invalidation
	"crlNo INTEGER, "               // Crl Number of CRL of first appearance
	"reasonBit INTEGER, "           // Bit number of the revocation reason
	"FOREIGN KEY (caId) REFERENCES items (id))"

/*
 * Templates
 */
<< "CREATE TABLE templates ("
	"item INTEGER, "                // reference to items(id)
	"version INTEGER, "             // Version of the template format
	"template " B64_BLOB ", "       // The base64 encoded template
	"FOREIGN KEY (item) REFERENCES items (id))"

/* Views */
<< "CREATE VIEW view_public_keys AS SELECT "
	"items.id, items.name, items.type AS item_type, items.date, "
	"items.source, items.comment, "
	"public_keys.type as key_type, public_keys.len, public_keys.\"public\", "
	"private_keys.ownPass, "
	"tokens.card_manufacturer, tokens.card_serial, tokens.card_model, "
	"tokens.card_label, tokens.slot_label, tokens.object_id "
	"FROM public_keys LEFT JOIN items ON public_keys.item = items.id "
	"LEFT JOIN private_keys ON private_keys.item = public_keys.item "
	"LEFT JOIN tokens ON public_keys.item = tokens.item"

<< "CREATE VIEW view_certs AS SELECT "
	"items.id, items.name, items.type, items.date AS item_date, "
	"items.source, items.comment, "
	"x509super.pkey, "
	"certs.serial AS certs_serial, certs.issuer, certs.ca, certs.cert, "
	"authority.template, authority.crlExpire, "
	"authority.crlNo AS auth_crlno, authority.crlDays, authority.dnPolicy, "
	"revocations.serial, revocations.date, revocations.invaldate, "
	"revocations.crlNo, revocations.reasonBit "
	"FROM certs LEFT JOIN items ON certs.item = items.id "
	"LEFT JOIN x509super ON x509super.item = certs.item "
	"LEFT JOIN authority ON authority.item = certs.item "
	"LEFT JOIN revocations ON revocations.caId = certs.issuer "
	                        "AND revocations.serial = certs.serial"

<< "CREATE VIEW view_requests AS SELECT "
	"items.id, items.name, items.type, items.date, "
	"items.source, items.comment, "
	"x509super.pkey, "
	"requests.request, requests.signed "
	"FROM requests LEFT JOIN items ON requests.item = items.id "
	"LEFT JOIN x509super ON x509super.item = requests.item"

<< "CREATE VIEW view_crls AS SELECT "
	"items.id, items.name, items.type, items.date, "
	"items.source, items.comment, "
	"crls.num, crls.issuer, crls.crl "
	"FROM crls LEFT JOIN items ON crls.item = items.id "

<< "CREATE VIEW view_templates AS SELECT "
	"items.id, items.name, items.type, items.date, "
	"items.source, items.comment, "
	"templates.version, templates.template "
	"FROM templates LEFT JOIN items ON templates.item = items.id"

<< "CREATE VIEW view_private AS SELECT "
	"name, private FROM private_keys JOIN items ON "
	"items.id = private_keys.item"


<< "CREATE INDEX i_settings_key_ ON settings (key_)"
<< "CREATE INDEX i_items_id ON items (id)"
<< "CREATE INDEX i_public_keys_item ON public_keys (item)"
<< "CREATE INDEX i_public_keys_hash ON public_keys (hash)"
<< "CREATE INDEX i_private_keys_item ON private_keys (item)"
<< "CREATE INDEX i_tokens_item ON tokens (item)"
<< "CREATE INDEX i_token_mechanism_item ON token_mechanism (item)"
<< "CREATE INDEX i_x509super_item ON x509super (item)"
<< "CREATE INDEX i_x509super_subj_hash ON x509super (subj_hash)"
<< "CREATE INDEX i_x509super_key_hash ON x509super (key_hash)"
<< "CREATE INDEX i_x509super_pkey ON x509super (pkey)"
<< "CREATE INDEX i_requests_item ON requests (item)"
<< "CREATE INDEX i_requests_hash ON requests (hash)"
<< "CREATE INDEX i_certs_item ON certs (item)"
<< "CREATE INDEX i_certs_hash ON certs (hash)"
<< "CREATE INDEX i_certs_iss_hash ON certs (iss_hash)"
<< "CREATE INDEX i_certs_serial ON certs (serial)"
<< "CREATE INDEX i_certs_issuer ON certs (issuer)"
<< "CREATE INDEX i_certs_ca ON certs (ca)"
<< "CREATE INDEX i_authority_item ON authority (item)"
<< "CREATE INDEX i_crls_item ON crls (item)"
<< "CREATE INDEX i_crls_hash ON crls (hash)"
<< "CREATE INDEX i_crls_iss_hash ON crls (iss_hash)"
<< "CREATE INDEX i_crls_issuer ON crls (issuer)"
<< "CREATE INDEX i_revocations_caId_serial ON revocations (caId, serial)"
<< "CREATE INDEX i_templates_item ON templates (item)"
<< "CREATE INDEX i_items_stamp ON items (stamp)"

	;
/* Schema Version 2: Views added to quickly load the data */

/* Schema Version 3: Add indexes over hashes and primary, foreign keys */

/* Schema Version 4: Add private key view to extract a private key with:
	mysql:      mysql -sNp -u xca xca_msq -e
	or sqlite:  sqlite3 ~/sqlxdb.xdb
	or psql:    psql -t -h 192.168.140.7 -U xca -d xca_pg -c
	        'SELECT private FROM view_private WHERE name=\"pk8key\";' |\
	        base64 -d | openssl pkcs8 -inform DER
 * First mysql/psql will ask for a password and then OpenSSL will ask for
 * the database password.
 */

/* Schema Version 5: Extend settings value size from 1024 to B64_BLOB
 * SQLite does not support 'ALTER TABLE settings MODIFY ...'
 */

	schemas[5]
<< "ALTER TABLE settings RENAME TO __settings"
<< "CREATE TABLE settings ("
	"key_ CHAR(20) UNIQUE, "        // mySql does not like 'key' or 'option'
	"value " B64_BLOB ")"
<< "INSERT INTO settings(key_, value) "
	"SELECT key_, value "
	"FROM __settings"
<< "DROP TABLE __settings"
<< "UPDATE settings SET value='6' WHERE key_='schema'"
	;

	schemas[6]
<< "ALTER TABLE items ADD del SMALLINT NOT NULL DEFAULT 0"
<< "CREATE INDEX i_items_del ON items (del)"
<< "UPDATE settings SET value='7' WHERE key_='schema'"
	;

	schemas[7]
// OpenVPN TA (tls-auth) keys associated to the CA to be
// the same for all issued certificates
<< "CREATE TABLE takeys ("
	"item INTEGER UNIQUE, "        // reference to items(id) of the CA
	"value " B64_BLOB ", "         // The base64 encoded 2048 bit key
	"FOREIGN KEY (item) REFERENCES items (id))"
<< "UPDATE settings SET value='8' WHERE key_='schema'"
	;

/* When adding new tables or views, also add them to the list
 * in XSqlQuery::rewriteQuery(QString) in lib/sql.cpp
 */