aboutsummaryrefslogtreecommitdiff
path: root/openssl/trunk/crypto/ec/ec_key.c
blob: 3d6c900b95a75b3624bb51810bf44373e21e9cde (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
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
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
/* crypto/ec/ec_key.c */
/*
 * Written by Nils Larsch for the OpenSSL project.
 */
/* ====================================================================
 * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 * Portions originally developed by SUN MICROSYSTEMS, INC., and 
 * contributed to the OpenSSL project.
 */

#include <string.h>
#include "ec_lcl.h"
#include <openssl/err.h>
#include <string.h>

EC_KEY *EC_KEY_new(void)
	{
	EC_KEY *ret;

	ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
	if (ret == NULL)
		{
		ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);
		return(NULL);
		}

	ret->version = 1;	
	ret->group   = NULL;
	ret->pub_key = NULL;
	ret->priv_key= NULL;
	ret->enc_flag= 0; 
	ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
	ret->references= 1;
	ret->method_data = NULL;
	return(ret);
	}

EC_KEY *EC_KEY_new_by_curve_name(int nid)
	{
	EC_KEY *ret = EC_KEY_new();
	if (ret == NULL)
		return NULL;
	ret->group = EC_GROUP_new_by_curve_name(nid);
	if (ret->group == NULL)
		{
		EC_KEY_free(ret);
		return NULL;
		}
	return ret;
	}

void EC_KEY_free(EC_KEY *r)
	{
	int i;

	if (r == NULL) return;

	i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC);
#ifdef REF_PRINT
	REF_PRINT("EC_KEY",r);
#endif
	if (i > 0) return;
#ifdef REF_CHECK
	if (i < 0)
		{
		fprintf(stderr,"EC_KEY_free, bad reference count\n");
		abort();
		}
#endif

	if (r->group    != NULL) 
		EC_GROUP_free(r->group);
	if (r->pub_key  != NULL)
		EC_POINT_free(r->pub_key);
	if (r->priv_key != NULL)
		BN_clear_free(r->priv_key);

	EC_EX_DATA_free_all_data(&r->method_data);

	OPENSSL_cleanse((void *)r, sizeof(EC_KEY));

	OPENSSL_free(r);
	}

EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
	{
	EC_EXTRA_DATA *d;

	if (dest == NULL || src == NULL)
		{
		ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
		return NULL;
		}
	/* copy the parameters */
	if (src->group)
		{
		const EC_METHOD *meth = EC_GROUP_method_of(src->group);
		/* clear the old group */
		if (dest->group)
			EC_GROUP_free(dest->group);
		dest->group = EC_GROUP_new(meth);
		if (dest->group == NULL)
			return NULL;
		if (!EC_GROUP_copy(dest->group, src->group))
			return NULL;
		}
	/*  copy the public key */
	if (src->pub_key && src->group)
		{
		if (dest->pub_key)
			EC_POINT_free(dest->pub_key);
		dest->pub_key = EC_POINT_new(src->group);
		if (dest->pub_key == NULL)
			return NULL;
		if (!EC_POINT_copy(dest->pub_key, src->pub_key))
			return NULL;
		}
	/* copy the private key */
	if (src->priv_key)
		{
		if (dest->priv_key == NULL)
			{
			dest->priv_key = BN_new();
			if (dest->priv_key == NULL)
				return NULL;
			}
		if (!BN_copy(dest->priv_key, src->priv_key))
			return NULL;
		}
	/* copy method/extra data */
	EC_EX_DATA_free_all_data(&dest->method_data);

	for (d = src->method_data; d != NULL; d = d->next)
		{
		void *t = d->dup_func(d->data);
		
		if (t == NULL)
			return 0;
		if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, d->free_func, d->clear_free_func))
			return 0;
		}

	/* copy the rest */
	dest->enc_flag  = src->enc_flag;
	dest->conv_form = src->conv_form;
	dest->version   = src->version;

	return dest;
	}

EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
	{
	EC_KEY *ret = EC_KEY_new();
	if (ret == NULL)
		return NULL;
	if (EC_KEY_copy(ret, ec_key) == NULL)
		{
		EC_KEY_free(ret);
		return NULL;
		}
	return ret;
	}

int EC_KEY_up_ref(EC_KEY *r)
	{
	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
#ifdef REF_PRINT
	REF_PRINT("EC_KEY",r);
#endif
#ifdef REF_CHECK
	if (i < 2)
		{
		fprintf(stderr, "EC_KEY_up, bad reference count\n");
		abort();
		}
#endif
	return ((i > 1) ? 1 : 0);
	}

int EC_KEY_generate_key(EC_KEY *eckey)
	{	
	int	ok = 0;
	BN_CTX	*ctx = NULL;
	BIGNUM	*priv_key = NULL, *order = NULL;
	EC_POINT *pub_key = NULL;

	if (!eckey || !eckey->group)
		{
		ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
		return 0;
		}

	if ((order = BN_new()) == NULL) goto err;
	if ((ctx = BN_CTX_new()) == NULL) goto err;

	if (eckey->priv_key == NULL)
		{
		priv_key = BN_new();
		if (priv_key == NULL)
			goto err;
		}
	else
		priv_key = eckey->priv_key;

	if (!EC_GROUP_get_order(eckey->group, order, ctx))
		goto err;

	do
		if (!BN_rand_range(priv_key, order))
			goto err;
	while (BN_is_zero(priv_key));

	if (eckey->pub_key == NULL)
		{
		pub_key = EC_POINT_new(eckey->group);
		if (pub_key == NULL)
			goto err;
		}
	else
		pub_key = eckey->pub_key;

	if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
		goto err;

	eckey->priv_key = priv_key;
	eckey->pub_key  = pub_key;

	ok=1;

err:	
	if (order)
		BN_free(order);
	if (pub_key  != NULL && eckey->pub_key  == NULL)
		EC_POINT_free(pub_key);
	if (priv_key != NULL && eckey->priv_key == NULL)
		BN_free(priv_key);
	if (ctx != NULL)
		BN_CTX_free(ctx);
	return(ok);
	}

int EC_KEY_check_key(const EC_KEY *eckey)
	{
	int	ok   = 0;
	BN_CTX	*ctx = NULL;
	BIGNUM	*order  = NULL;
	EC_POINT *point = NULL;

	if (!eckey || !eckey->group || !eckey->pub_key)
		{
		ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
		return 0;
		}
	
	if ((ctx = BN_CTX_new()) == NULL)
		goto err;
	if ((order = BN_new()) == NULL)
		goto err;
	if ((point = EC_POINT_new(eckey->group)) == NULL)
		goto err;

	/* testing whether the pub_key is on the elliptic curve */
	if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx))
		{
		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
		goto err;
		}
	/* testing whether pub_key * order is the point at infinity */
	if (!EC_GROUP_get_order(eckey->group, order, ctx))
		{
		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
		goto err;
		}
	if (!EC_POINT_copy(point, eckey->pub_key))
		{
		ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
		goto err;
		}
	if (!EC_POINT_mul(eckey->group, point, order, NULL, NULL, ctx))
		{
		ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
		goto err;
		}
	if (!EC_POINT_is_at_infinity(eckey->group, point))
		{
		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
		goto err;
		}
	/* in case the priv_key is present : 
	 * check if generator * priv_key == pub_key 
	 */
	if (eckey->priv_key)
		{
		if (BN_cmp(eckey->priv_key, order) >= 0)
			{
			ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
			goto err;
			}
		if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
			NULL, NULL, ctx))
			{
			ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
			goto err;
			}
		if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, 
			ctx) != 0)
			{
			ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
			goto err;
			}
		}
	ok = 1;
err:
	if (ctx   != NULL)
		BN_CTX_free(ctx);
	if (order != NULL)
		BN_free(order);
	if (point != NULL)
		EC_POINT_free(point);
	return(ok);
	}

const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
	{
	return key->group;
	}

int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
	{
	if (key->group != NULL)
		EC_GROUP_free(key->group);
	key->group = EC_GROUP_dup(group);
	return (key->group == NULL) ? 0 : 1;
	}

const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
	{
	return key->priv_key;
	}

int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
	{
	if (key->priv_key)
		BN_clear_free(key->priv_key);
	key->priv_key = BN_dup(priv_key);
	return (key->priv_key == NULL) ? 0 : 1;
	}

const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
	{
	return key->pub_key;
	}

int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
	{
	if (key->pub_key != NULL)
		EC_POINT_free(key->pub_key);
	key->pub_key = EC_POINT_dup(pub_key, key->group);
	return (key->pub_key == NULL) ? 0 : 1;
	}

unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
	{
	return key->enc_flag;
	}

void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
	{
	key->enc_flag = flags;
	}

point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
	{
	return key->conv_form;
	}

void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
	{
	key->conv_form = cform;
	if (key->group != NULL)
		EC_GROUP_set_point_conversion_form(key->group, cform);
	}

void *EC_KEY_get_key_method_data(EC_KEY *key,
	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
	{
	return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
	}

void EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
	{
	EC_EXTRA_DATA *ex_data;
	CRYPTO_w_lock(CRYPTO_LOCK_EC);
	ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
	if (ex_data == NULL)
		EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
	CRYPTO_w_unlock(CRYPTO_LOCK_EC);
	}

void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
	{
	if (key->group != NULL)
		EC_GROUP_set_asn1_flag(key->group, flag);
	}

int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
	{
	if (key->group == NULL)
		return 0;
	return EC_GROUP_precompute_mult(key->group, ctx);
	}
pan>("repository_xml", help = "XML file containing repository response")) def do_configure_repository(self, args): """ Configure a publication repository for this RPKI entity. This command reads the repository's response to this entity's request for publication service, extracts and cross-certifies the BPKI data and service URI, and links the repository data with the corresponding parent data in our local database. """ self.zoo.configure_repository(args.repository_xml, args.parent_handle) self.zoo.synchronize_ca() @parsecmd(argsubparsers, cmdarg("repository_handle", help = "handle of repository to delete")) def do_delete_repository(self, args): """ Delete a repository of this RPKI entity. """ try: self.zoo.delete_repository(args.repository_handle) self.zoo.synchronize_ca() except rpki.irdb.ResourceHolderCA.DoesNotExist: print "No such resource holder \"%s\"" % self.zoo.handle except rpki.irdb.Repository.DoesNotExist: print "No such repository \"%s\"" % args.repository_handle def complete_delete_repository(self, *args): return self.irdb_handle_complete(self.zoo.resource_ca.repositories, *args) @parsecmd(argsubparsers) def do_delete_identity(self, args): """ Delete the current RPKI identity (rpkid <self/> object). """ try: self.zoo.delete_self() self.zoo.synchronize_deleted_ca() except rpki.irdb.ResourceHolderCA.DoesNotExist: print "No such resource holder \"%s\"" % self.zoo.handle @parsecmd(argsubparsers, cmdarg("--valid_until", help = "override default new validity interval"), cmdarg("child_handle", help = "handle of child to renew")) def do_renew_child(self, args): """ Update validity period for one child entity. """ self.zoo.renew_children(args.child_handle, args.valid_until) self.zoo.synchronize_ca() if self.autosync: self.zoo.run_rpkid_now() def complete_renew_child(self, *args): return self.irdb_handle_complete(self.zoo.resource_ca.children, *args) @parsecmd(argsubparsers, cmdarg("--valid_until", help = "override default new validity interval")) def do_renew_all_children(self, args): """ Update validity period for all child entities. """ self.zoo.renew_children(None, args.valid_until) self.zoo.synchronize_ca() if self.autosync: self.zoo.run_rpkid_now() @parsecmd(argsubparsers, cmdarg("prefixes_csv", help = "CSV file listing prefixes")) def do_load_prefixes(self, args): """ Load prefixes into IRDB from CSV file. """ self.zoo.load_prefixes(args.prefixes_csv, True) if self.autosync: self.zoo.run_rpkid_now() @parsecmd(argsubparsers) def do_show_child_resources(self, args): """ Show resources assigned to children. """ for child in self.zoo.resource_ca.children.all(): resources = child.resource_bag print "Child:", child.handle if resources.asn: print " ASN:", resources.asn if resources.v4: print " IPv4:", resources.v4 if resources.v6: print " IPv6:", resources.v6 @parsecmd(argsubparsers) def do_show_roa_requests(self, args): """ Show ROA requests. """ for roa_request in self.zoo.resource_ca.roa_requests.all(): prefixes = roa_request.roa_prefix_bag print "ASN: ", roa_request.asn if prefixes.v4: print " IPv4:", prefixes.v4 if prefixes.v6: print " IPv6:", prefixes.v6 @parsecmd(argsubparsers) def do_show_ghostbuster_requests(self, args): """ Show Ghostbuster requests. """ for ghostbuster_request in self.zoo.resource_ca.ghostbuster_requests.all(): print "Parent:", ghostbuster_request.parent or "*" print ghostbuster_request.vcard @parsecmd(argsubparsers) def do_show_received_resources(self, args): """ Show resources received by this entity from its parent(s). """ for pdu in self.zoo.call_rpkid( rpki.left_right.list_received_resources_elt.make_pdu(self_handle = self.zoo.handle)): print "Parent: ", pdu.parent_handle print " notBefore:", pdu.notBefore print " notAfter: ", pdu.notAfter print " URI: ", pdu.uri print " SIA URI: ", pdu.sia_uri print " AIA URI: ", pdu.aia_uri print " ASN: ", pdu.asn print " IPv4: ", pdu.ipv4 print " IPv6: ", pdu.ipv6 @parsecmd(argsubparsers) def do_show_published_objects(self, args): """ Show published objects. """ for pdu in self.zoo.call_rpkid( rpki.left_right.list_published_objects_elt.make_pdu(self_handle = self.zoo.handle)): track = rpki.x509.uri_dispatch(pdu.uri)(Base64 = pdu.obj).tracking_data(pdu.uri) child = pdu.child_handle if child is None: print track else: print track, child @parsecmd(argsubparsers) def do_show_bpki(self, args): """ Show this entity's BPKI objects. """ print "Self: ", self.zoo.resource_ca.handle print " notBefore:", self.zoo.resource_ca.certificate.getNotBefore() print " notAfter: ", self.zoo.resource_ca.certificate.getNotAfter() print " Subject: ", self.zoo.resource_ca.certificate.getSubject() print " SKI: ", self.zoo.resource_ca.certificate.hSKI() for bsc in self.zoo.resource_ca.bscs.all(): print "BSC: ", bsc.handle print " notBefore:", bsc.certificate.getNotBefore() print " notAfter: ", bsc.certificate.getNotAfter() print " Subject: ", bsc.certificate.getSubject() print " SKI: ", bsc.certificate.hSKI() for parent in self.zoo.resource_ca.parents.all(): print "Parent: ", parent.handle print " notBefore:", parent.certificate.getNotBefore() print " notAfter: ", parent.certificate.getNotAfter() print " Subject: ", parent.certificate.getSubject() print " SKI: ", parent.certificate.hSKI() print " URL: ", parent.service_uri for child in self.zoo.resource_ca.children.all(): print "Child: ", child.handle print " notBefore:", child.certificate.getNotBefore() print " notAfter: ", child.certificate.getNotAfter() print " Subject: ", child.certificate.getSubject() print " SKI: ", child.certificate.hSKI() for repository in self.zoo.resource_ca.repositories.all(): print "Repository: ", repository.handle print " notBefore:", repository.certificate.getNotBefore() print " notAfter: ", repository.certificate.getNotAfter() print " Subject: ", repository.certificate.getSubject() print " SKI: ", repository.certificate.hSKI() print " URL: ", repository.service_uri @parsecmd(argsubparsers, cmdarg("asns_csv", help = "CSV file listing ASNs")) def do_load_asns(self, args): """ Load ASNs into IRDB from CSV file. """ self.zoo.load_asns(args.asns_csv, True) if self.autosync: self.zoo.run_rpkid_now() @parsecmd(argsubparsers, cmdarg("roa_requests_csv", help = "CSV file listing ROA requests")) def do_load_roa_requests(self, args): """ Load ROA requests into IRDB from CSV file. """ self.zoo.load_roa_requests(args.roa_requests_csv) if self.autosync: self.zoo.run_rpkid_now() @parsecmd(argsubparsers, cmdarg("ghostbuster_requests", help = "file listing Ghostbuster requests as a sequence of VCards")) def do_load_ghostbuster_requests(self, args): """ Load Ghostbuster requests into IRDB from file. """ self.zoo.load_ghostbuster_requests(args.ghostbuster_requests) if self.autosync: self.zoo.run_rpkid_now() @parsecmd(argsubparsers, cmdarg("--valid_until", help = "override default validity interval"), cmdarg("router_certificate_request_xml", help = "file containing XML router certificate request")) def do_add_router_certificate_request(self, args): """ Load router certificate request(s) into IRDB from XML file. """ self.zoo.add_router_certificate_request(args.router_certificate_request_xml, args.valid_until) if self.autosync: self.zoo.run_rpkid_now() @parsecmd(argsubparsers, cmdarg("gski", help = "g(SKI) of router certificate request to delete")) def do_delete_router_certificate_request(self, args): """ Delete a router certificate request from the IRDB. """ try: self.zoo.delete_router_certificate_request(args.gski) if self.autosync: self.zoo.run_rpkid_now() except rpki.irdb.ResourceHolderCA.DoesNotExist: print "No such resource holder \"%s\"" % self.zoo.handle except rpki.irdb.EECertificateRequest.DoesNotExist: print "No certificate request matching g(SKI) \"%s\"" % args.gski def complete_delete_router_certificate_request(self, text, line, begidx, endidx): return [obj.gski for obj in self.zoo.resource_ca.ee_certificate_requests.all() if obj.gski and obj.gski.startswith(text)] @parsecmd(argsubparsers) def do_show_router_certificate_requests(self, args): """ Show this entity's router certificate requests. """ for req in self.zoo.resource_ca.ee_certificate_requests.all(): print "%s %s %s %s" % (req.gski, req.valid_until, req.cn, req.sn) # What about updates? Validity interval, change router-id, change # ASNs. Not sure what this looks like yet, blunder ahead with the # core code while mulling over the UI. @parsecmd(argsubparsers) def do_synchronize(self, args): """ Whack daemons to match IRDB. This command may be replaced by implicit synchronization embedded in of other commands, haven't decided yet. """ self.zoo.synchronize() @parsecmd(argsubparsers) def do_force_publication(self, args): """ Whack rpkid to force (re)publication of everything. This is not usually necessary, as rpkid automatically publishes changes it makes, but this command can be useful occasionally when a fault or configuration error has left rpkid holding data which it has not been able to publish. """ self.zoo.publish_world_now() @parsecmd(argsubparsers) def do_force_reissue(self, args): """ Whack rpkid to force reissuance of everything. This is not usually necessary, as rpkid reissues automatically objects automatically as needed, but this command can be useful occasionally when a fault or configuration error has prevented rpkid from reissuing when it should have. """ self.zoo.reissue() @parsecmd(argsubparsers) def do_up_down_rekey(self, args): """ Initiate a "rekey" operation. This tells rpkid to generate new keys for each certificate issued to it via the up-down protocol. Rekeying is the first stage of a key rollover operation. You will need to follow it up later with a "revoke" operation to clean up the old keys """ self.zoo.rekey() @parsecmd(argsubparsers) def do_up_down_revoke(self, args): """ Initiate a "revoke" operation. This tells rpkid to clean up old keys formerly used by certificates issued to it via the up-down protocol. This is the cleanup stage of a key rollover operation. """ self.zoo.revoke() @parsecmd(argsubparsers) def do_revoke_forgotten(self, args): """ Initiate a "revoke_forgotten" operation. This tells rpkid to ask its parent to revoke certificates for which rpkid does not know the private keys. This should never happen during ordinary operation, but can happen if rpkid is misconfigured or its database has been damaged, so we need a way to resynchronize rpkid with its parent in such cases. We could do this automatically, but as we don't know the precise cause of the failure we don't know if it's recoverable locally (eg, from an SQL backup), so we require a manual trigger before discarding possibly-useful certificates. """ self.zoo.revoke_forgotten() @parsecmd(argsubparsers) def do_clear_all_sql_cms_replay_protection(self, args): """ Tell rpkid and pubd to clear replay protection. This clears the replay protection timestamps stored in SQL for all entities known to rpkid and pubd. This is a fairly blunt instrument, but as we don't expect this to be necessary except in the case of gross misconfiguration, it should suffice """ self.zoo.clear_all_sql_cms_replay_protection() @parsecmd(argsubparsers) def do_version(self, args): """ Show current software version number. """ print rpki.version.VERSION @parsecmd(argsubparsers) def do_list_self_handles(self, args): """ List all <self/> handles in this rpkid instance. """ for ca in rpki.irdb.ResourceHolderCA.objects.all(): print ca.handle