diff options
Diffstat (limited to 'key.c')
-rw-r--r-- | key.c | 613 |
1 files changed, 578 insertions, 35 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: key.c,v 1.80 2008/10/10 05:00:12 stevesk Exp $ */ | 1 | /* $OpenBSD: key.c,v 1.85 2010/03/04 01:44:57 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * read_bignum(): | 3 | * read_bignum(): |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -52,6 +52,21 @@ | |||
52 | #include "uuencode.h" | 52 | #include "uuencode.h" |
53 | #include "buffer.h" | 53 | #include "buffer.h" |
54 | #include "log.h" | 54 | #include "log.h" |
55 | #include "ssh2.h" | ||
56 | |||
57 | static struct KeyCert * | ||
58 | cert_new(void) | ||
59 | { | ||
60 | struct KeyCert *cert; | ||
61 | |||
62 | cert = xcalloc(1, sizeof(*cert)); | ||
63 | buffer_init(&cert->certblob); | ||
64 | buffer_init(&cert->constraints); | ||
65 | cert->key_id = NULL; | ||
66 | cert->principals = NULL; | ||
67 | cert->signature_key = NULL; | ||
68 | return cert; | ||
69 | } | ||
55 | 70 | ||
56 | Key * | 71 | Key * |
57 | key_new(int type) | 72 | key_new(int type) |
@@ -63,9 +78,11 @@ key_new(int type) | |||
63 | k->type = type; | 78 | k->type = type; |
64 | k->dsa = NULL; | 79 | k->dsa = NULL; |
65 | k->rsa = NULL; | 80 | k->rsa = NULL; |
81 | k->cert = NULL; | ||
66 | switch (k->type) { | 82 | switch (k->type) { |
67 | case KEY_RSA1: | 83 | case KEY_RSA1: |
68 | case KEY_RSA: | 84 | case KEY_RSA: |
85 | case KEY_RSA_CERT: | ||
69 | if ((rsa = RSA_new()) == NULL) | 86 | if ((rsa = RSA_new()) == NULL) |
70 | fatal("key_new: RSA_new failed"); | 87 | fatal("key_new: RSA_new failed"); |
71 | if ((rsa->n = BN_new()) == NULL) | 88 | if ((rsa->n = BN_new()) == NULL) |
@@ -75,6 +92,7 @@ key_new(int type) | |||
75 | k->rsa = rsa; | 92 | k->rsa = rsa; |
76 | break; | 93 | break; |
77 | case KEY_DSA: | 94 | case KEY_DSA: |
95 | case KEY_DSA_CERT: | ||
78 | if ((dsa = DSA_new()) == NULL) | 96 | if ((dsa = DSA_new()) == NULL) |
79 | fatal("key_new: DSA_new failed"); | 97 | fatal("key_new: DSA_new failed"); |
80 | if ((dsa->p = BN_new()) == NULL) | 98 | if ((dsa->p = BN_new()) == NULL) |
@@ -93,16 +111,20 @@ key_new(int type) | |||
93 | fatal("key_new: bad key type %d", k->type); | 111 | fatal("key_new: bad key type %d", k->type); |
94 | break; | 112 | break; |
95 | } | 113 | } |
114 | |||
115 | if (key_is_cert(k)) | ||
116 | k->cert = cert_new(); | ||
117 | |||
96 | return k; | 118 | return k; |
97 | } | 119 | } |
98 | 120 | ||
99 | Key * | 121 | void |
100 | key_new_private(int type) | 122 | key_add_private(Key *k) |
101 | { | 123 | { |
102 | Key *k = key_new(type); | ||
103 | switch (k->type) { | 124 | switch (k->type) { |
104 | case KEY_RSA1: | 125 | case KEY_RSA1: |
105 | case KEY_RSA: | 126 | case KEY_RSA: |
127 | case KEY_RSA_CERT: | ||
106 | if ((k->rsa->d = BN_new()) == NULL) | 128 | if ((k->rsa->d = BN_new()) == NULL) |
107 | fatal("key_new_private: BN_new failed"); | 129 | fatal("key_new_private: BN_new failed"); |
108 | if ((k->rsa->iqmp = BN_new()) == NULL) | 130 | if ((k->rsa->iqmp = BN_new()) == NULL) |
@@ -117,6 +139,7 @@ key_new_private(int type) | |||
117 | fatal("key_new_private: BN_new failed"); | 139 | fatal("key_new_private: BN_new failed"); |
118 | break; | 140 | break; |
119 | case KEY_DSA: | 141 | case KEY_DSA: |
142 | case KEY_DSA_CERT: | ||
120 | if ((k->dsa->priv_key = BN_new()) == NULL) | 143 | if ((k->dsa->priv_key = BN_new()) == NULL) |
121 | fatal("key_new_private: BN_new failed"); | 144 | fatal("key_new_private: BN_new failed"); |
122 | break; | 145 | break; |
@@ -125,9 +148,34 @@ key_new_private(int type) | |||
125 | default: | 148 | default: |
126 | break; | 149 | break; |
127 | } | 150 | } |
151 | } | ||
152 | |||
153 | Key * | ||
154 | key_new_private(int type) | ||
155 | { | ||
156 | Key *k = key_new(type); | ||
157 | |||
158 | key_add_private(k); | ||
128 | return k; | 159 | return k; |
129 | } | 160 | } |
130 | 161 | ||
162 | static void | ||
163 | cert_free(struct KeyCert *cert) | ||
164 | { | ||
165 | u_int i; | ||
166 | |||
167 | buffer_free(&cert->certblob); | ||
168 | buffer_free(&cert->constraints); | ||
169 | if (cert->key_id != NULL) | ||
170 | xfree(cert->key_id); | ||
171 | for (i = 0; i < cert->nprincipals; i++) | ||
172 | xfree(cert->principals[i]); | ||
173 | if (cert->principals != NULL) | ||
174 | xfree(cert->principals); | ||
175 | if (cert->signature_key != NULL) | ||
176 | key_free(cert->signature_key); | ||
177 | } | ||
178 | |||
131 | void | 179 | void |
132 | key_free(Key *k) | 180 | key_free(Key *k) |
133 | { | 181 | { |
@@ -136,11 +184,13 @@ key_free(Key *k) | |||
136 | switch (k->type) { | 184 | switch (k->type) { |
137 | case KEY_RSA1: | 185 | case KEY_RSA1: |
138 | case KEY_RSA: | 186 | case KEY_RSA: |
187 | case KEY_RSA_CERT: | ||
139 | if (k->rsa != NULL) | 188 | if (k->rsa != NULL) |
140 | RSA_free(k->rsa); | 189 | RSA_free(k->rsa); |
141 | k->rsa = NULL; | 190 | k->rsa = NULL; |
142 | break; | 191 | break; |
143 | case KEY_DSA: | 192 | case KEY_DSA: |
193 | case KEY_DSA_CERT: | ||
144 | if (k->dsa != NULL) | 194 | if (k->dsa != NULL) |
145 | DSA_free(k->dsa); | 195 | DSA_free(k->dsa); |
146 | k->dsa = NULL; | 196 | k->dsa = NULL; |
@@ -151,20 +201,49 @@ key_free(Key *k) | |||
151 | fatal("key_free: bad key type %d", k->type); | 201 | fatal("key_free: bad key type %d", k->type); |
152 | break; | 202 | break; |
153 | } | 203 | } |
204 | if (key_is_cert(k)) { | ||
205 | if (k->cert != NULL) | ||
206 | cert_free(k->cert); | ||
207 | k->cert = NULL; | ||
208 | } | ||
209 | |||
154 | xfree(k); | 210 | xfree(k); |
155 | } | 211 | } |
156 | 212 | ||
213 | static int | ||
214 | cert_compare(struct KeyCert *a, struct KeyCert *b) | ||
215 | { | ||
216 | if (a == NULL && b == NULL) | ||
217 | return 1; | ||
218 | if (a == NULL || b == NULL) | ||
219 | return 0; | ||
220 | if (buffer_len(&a->certblob) != buffer_len(&b->certblob)) | ||
221 | return 0; | ||
222 | if (memcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob), | ||
223 | buffer_len(&a->certblob)) != 0) | ||
224 | return 0; | ||
225 | return 1; | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * Compare public portions of key only, allowing comparisons between | ||
230 | * certificates and plain keys too. | ||
231 | */ | ||
157 | int | 232 | int |
158 | key_equal(const Key *a, const Key *b) | 233 | key_equal_public(const Key *a, const Key *b) |
159 | { | 234 | { |
160 | if (a == NULL || b == NULL || a->type != b->type) | 235 | if (a == NULL || b == NULL || |
236 | key_type_plain(a->type) != key_type_plain(b->type)) | ||
161 | return 0; | 237 | return 0; |
238 | |||
162 | switch (a->type) { | 239 | switch (a->type) { |
163 | case KEY_RSA1: | 240 | case KEY_RSA1: |
241 | case KEY_RSA_CERT: | ||
164 | case KEY_RSA: | 242 | case KEY_RSA: |
165 | return a->rsa != NULL && b->rsa != NULL && | 243 | return a->rsa != NULL && b->rsa != NULL && |
166 | BN_cmp(a->rsa->e, b->rsa->e) == 0 && | 244 | BN_cmp(a->rsa->e, b->rsa->e) == 0 && |
167 | BN_cmp(a->rsa->n, b->rsa->n) == 0; | 245 | BN_cmp(a->rsa->n, b->rsa->n) == 0; |
246 | case KEY_DSA_CERT: | ||
168 | case KEY_DSA: | 247 | case KEY_DSA: |
169 | return a->dsa != NULL && b->dsa != NULL && | 248 | return a->dsa != NULL && b->dsa != NULL && |
170 | BN_cmp(a->dsa->p, b->dsa->p) == 0 && | 249 | BN_cmp(a->dsa->p, b->dsa->p) == 0 && |
@@ -177,16 +256,27 @@ key_equal(const Key *a, const Key *b) | |||
177 | /* NOTREACHED */ | 256 | /* NOTREACHED */ |
178 | } | 257 | } |
179 | 258 | ||
259 | int | ||
260 | key_equal(const Key *a, const Key *b) | ||
261 | { | ||
262 | if (a == NULL || b == NULL || a->type != b->type) | ||
263 | return 0; | ||
264 | if (key_is_cert(a)) { | ||
265 | if (!cert_compare(a->cert, b->cert)) | ||
266 | return 0; | ||
267 | } | ||
268 | return key_equal_public(a, b); | ||
269 | } | ||
270 | |||
180 | u_char* | 271 | u_char* |
181 | key_fingerprint_raw(const Key *k, enum fp_type dgst_type, | 272 | key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) |
182 | u_int *dgst_raw_length) | ||
183 | { | 273 | { |
184 | const EVP_MD *md = NULL; | 274 | const EVP_MD *md = NULL; |
185 | EVP_MD_CTX ctx; | 275 | EVP_MD_CTX ctx; |
186 | u_char *blob = NULL; | 276 | u_char *blob = NULL; |
187 | u_char *retval = NULL; | 277 | u_char *retval = NULL; |
188 | u_int len = 0; | 278 | u_int len = 0; |
189 | int nlen, elen; | 279 | int nlen, elen, otype; |
190 | 280 | ||
191 | *dgst_raw_length = 0; | 281 | *dgst_raw_length = 0; |
192 | 282 | ||
@@ -214,6 +304,14 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type, | |||
214 | case KEY_RSA: | 304 | case KEY_RSA: |
215 | key_to_blob(k, &blob, &len); | 305 | key_to_blob(k, &blob, &len); |
216 | break; | 306 | break; |
307 | case KEY_DSA_CERT: | ||
308 | case KEY_RSA_CERT: | ||
309 | /* We want a fingerprint of the _key_ not of the cert */ | ||
310 | otype = k->type; | ||
311 | k->type = key_type_plain(k->type); | ||
312 | key_to_blob(k, &blob, &len); | ||
313 | k->type = otype; | ||
314 | break; | ||
217 | case KEY_UNSPEC: | 315 | case KEY_UNSPEC: |
218 | return retval; | 316 | return retval; |
219 | default: | 317 | default: |
@@ -408,7 +506,7 @@ key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k) | |||
408 | } | 506 | } |
409 | 507 | ||
410 | char * | 508 | char * |
411 | key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) | 509 | key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) |
412 | { | 510 | { |
413 | char *retval = NULL; | 511 | char *retval = NULL; |
414 | u_char *dgst_raw; | 512 | u_char *dgst_raw; |
@@ -522,11 +620,19 @@ key_read(Key *ret, char **cpp) | |||
522 | return -1; | 620 | return -1; |
523 | if (!read_bignum(cpp, ret->rsa->n)) | 621 | if (!read_bignum(cpp, ret->rsa->n)) |
524 | return -1; | 622 | return -1; |
623 | /* validate the claimed number of bits */ | ||
624 | if ((u_int)BN_num_bits(ret->rsa->n) != bits) { | ||
625 | verbose("key_read: claimed key size %d does not match " | ||
626 | "actual %d", bits, BN_num_bits(ret->rsa->n)); | ||
627 | return -1; | ||
628 | } | ||
525 | success = 1; | 629 | success = 1; |
526 | break; | 630 | break; |
527 | case KEY_UNSPEC: | 631 | case KEY_UNSPEC: |
528 | case KEY_RSA: | 632 | case KEY_RSA: |
529 | case KEY_DSA: | 633 | case KEY_DSA: |
634 | case KEY_DSA_CERT: | ||
635 | case KEY_RSA_CERT: | ||
530 | space = strchr(cp, ' '); | 636 | space = strchr(cp, ' '); |
531 | if (space == NULL) { | 637 | if (space == NULL) { |
532 | debug3("key_read: missing whitespace"); | 638 | debug3("key_read: missing whitespace"); |
@@ -571,25 +677,36 @@ key_read(Key *ret, char **cpp) | |||
571 | return -1; | 677 | return -1; |
572 | } | 678 | } |
573 | /*XXXX*/ | 679 | /*XXXX*/ |
574 | if (ret->type == KEY_RSA) { | 680 | if (key_is_cert(ret)) { |
681 | if (!key_is_cert(k)) { | ||
682 | error("key_read: loaded key is not a cert"); | ||
683 | key_free(k); | ||
684 | return -1; | ||
685 | } | ||
686 | if (ret->cert != NULL) | ||
687 | cert_free(ret->cert); | ||
688 | ret->cert = k->cert; | ||
689 | k->cert = NULL; | ||
690 | } | ||
691 | if (key_type_plain(ret->type) == KEY_RSA) { | ||
575 | if (ret->rsa != NULL) | 692 | if (ret->rsa != NULL) |
576 | RSA_free(ret->rsa); | 693 | RSA_free(ret->rsa); |
577 | ret->rsa = k->rsa; | 694 | ret->rsa = k->rsa; |
578 | k->rsa = NULL; | 695 | k->rsa = NULL; |
579 | success = 1; | ||
580 | #ifdef DEBUG_PK | 696 | #ifdef DEBUG_PK |
581 | RSA_print_fp(stderr, ret->rsa, 8); | 697 | RSA_print_fp(stderr, ret->rsa, 8); |
582 | #endif | 698 | #endif |
583 | } else { | 699 | } |
700 | if (key_type_plain(ret->type) == KEY_DSA) { | ||
584 | if (ret->dsa != NULL) | 701 | if (ret->dsa != NULL) |
585 | DSA_free(ret->dsa); | 702 | DSA_free(ret->dsa); |
586 | ret->dsa = k->dsa; | 703 | ret->dsa = k->dsa; |
587 | k->dsa = NULL; | 704 | k->dsa = NULL; |
588 | success = 1; | ||
589 | #ifdef DEBUG_PK | 705 | #ifdef DEBUG_PK |
590 | DSA_print_fp(stderr, ret->dsa, 8); | 706 | DSA_print_fp(stderr, ret->dsa, 8); |
591 | #endif | 707 | #endif |
592 | } | 708 | } |
709 | success = 1; | ||
593 | /*XXXX*/ | 710 | /*XXXX*/ |
594 | key_free(k); | 711 | key_free(k); |
595 | if (success != 1) | 712 | if (success != 1) |
@@ -616,28 +733,53 @@ key_write(const Key *key, FILE *f) | |||
616 | u_char *blob; | 733 | u_char *blob; |
617 | char *uu; | 734 | char *uu; |
618 | 735 | ||
619 | if (key->type == KEY_RSA1 && key->rsa != NULL) { | 736 | if (key_is_cert(key)) { |
737 | if (key->cert == NULL) { | ||
738 | error("%s: no cert data", __func__); | ||
739 | return 0; | ||
740 | } | ||
741 | if (buffer_len(&key->cert->certblob) == 0) { | ||
742 | error("%s: no signed certificate blob", __func__); | ||
743 | return 0; | ||
744 | } | ||
745 | } | ||
746 | |||
747 | switch (key->type) { | ||
748 | case KEY_RSA1: | ||
749 | if (key->rsa == NULL) | ||
750 | return 0; | ||
620 | /* size of modulus 'n' */ | 751 | /* size of modulus 'n' */ |
621 | bits = BN_num_bits(key->rsa->n); | 752 | bits = BN_num_bits(key->rsa->n); |
622 | fprintf(f, "%u", bits); | 753 | fprintf(f, "%u", bits); |
623 | if (write_bignum(f, key->rsa->e) && | 754 | if (write_bignum(f, key->rsa->e) && |
624 | write_bignum(f, key->rsa->n)) { | 755 | write_bignum(f, key->rsa->n)) |
625 | success = 1; | 756 | return 1; |
626 | } else { | 757 | error("key_write: failed for RSA key"); |
627 | error("key_write: failed for RSA key"); | 758 | return 0; |
628 | } | 759 | case KEY_DSA: |
629 | } else if ((key->type == KEY_DSA && key->dsa != NULL) || | 760 | case KEY_DSA_CERT: |
630 | (key->type == KEY_RSA && key->rsa != NULL)) { | 761 | if (key->dsa == NULL) |
631 | key_to_blob(key, &blob, &len); | 762 | return 0; |
632 | uu = xmalloc(2*len); | 763 | break; |
633 | n = uuencode(blob, len, uu, 2*len); | 764 | case KEY_RSA: |
634 | if (n > 0) { | 765 | case KEY_RSA_CERT: |
635 | fprintf(f, "%s %s", key_ssh_name(key), uu); | 766 | if (key->rsa == NULL) |
636 | success = 1; | 767 | return 0; |
637 | } | 768 | break; |
638 | xfree(blob); | 769 | default: |
639 | xfree(uu); | 770 | return 0; |
771 | } | ||
772 | |||
773 | key_to_blob(key, &blob, &len); | ||
774 | uu = xmalloc(2*len); | ||
775 | n = uuencode(blob, len, uu, 2*len); | ||
776 | if (n > 0) { | ||
777 | fprintf(f, "%s %s", key_ssh_name(key), uu); | ||
778 | success = 1; | ||
640 | } | 779 | } |
780 | xfree(blob); | ||
781 | xfree(uu); | ||
782 | |||
641 | return success; | 783 | return success; |
642 | } | 784 | } |
643 | 785 | ||
@@ -651,6 +793,10 @@ key_type(const Key *k) | |||
651 | return "RSA"; | 793 | return "RSA"; |
652 | case KEY_DSA: | 794 | case KEY_DSA: |
653 | return "DSA"; | 795 | return "DSA"; |
796 | case KEY_RSA_CERT: | ||
797 | return "RSA-CERT"; | ||
798 | case KEY_DSA_CERT: | ||
799 | return "DSA-CERT"; | ||
654 | } | 800 | } |
655 | return "unknown"; | 801 | return "unknown"; |
656 | } | 802 | } |
@@ -663,6 +809,10 @@ key_ssh_name(const Key *k) | |||
663 | return "ssh-rsa"; | 809 | return "ssh-rsa"; |
664 | case KEY_DSA: | 810 | case KEY_DSA: |
665 | return "ssh-dss"; | 811 | return "ssh-dss"; |
812 | case KEY_RSA_CERT: | ||
813 | return "ssh-rsa-cert-v00@openssh.com"; | ||
814 | case KEY_DSA_CERT: | ||
815 | return "ssh-dss-cert-v00@openssh.com"; | ||
666 | } | 816 | } |
667 | return "ssh-unknown"; | 817 | return "ssh-unknown"; |
668 | } | 818 | } |
@@ -673,8 +823,10 @@ key_size(const Key *k) | |||
673 | switch (k->type) { | 823 | switch (k->type) { |
674 | case KEY_RSA1: | 824 | case KEY_RSA1: |
675 | case KEY_RSA: | 825 | case KEY_RSA: |
826 | case KEY_RSA_CERT: | ||
676 | return BN_num_bits(k->rsa->n); | 827 | return BN_num_bits(k->rsa->n); |
677 | case KEY_DSA: | 828 | case KEY_DSA: |
829 | case KEY_DSA_CERT: | ||
678 | return BN_num_bits(k->dsa->p); | 830 | return BN_num_bits(k->dsa->p); |
679 | } | 831 | } |
680 | return 0; | 832 | return 0; |
@@ -685,7 +837,7 @@ rsa_generate_private_key(u_int bits) | |||
685 | { | 837 | { |
686 | RSA *private; | 838 | RSA *private; |
687 | 839 | ||
688 | private = RSA_generate_key(bits, 35, NULL, NULL); | 840 | private = RSA_generate_key(bits, RSA_F4, NULL, NULL); |
689 | if (private == NULL) | 841 | if (private == NULL) |
690 | fatal("rsa_generate_private_key: key generation failed."); | 842 | fatal("rsa_generate_private_key: key generation failed."); |
691 | return private; | 843 | return private; |
@@ -717,6 +869,9 @@ key_generate(int type, u_int bits) | |||
717 | case KEY_RSA1: | 869 | case KEY_RSA1: |
718 | k->rsa = rsa_generate_private_key(bits); | 870 | k->rsa = rsa_generate_private_key(bits); |
719 | break; | 871 | break; |
872 | case KEY_RSA_CERT: | ||
873 | case KEY_DSA_CERT: | ||
874 | fatal("key_generate: cert keys cannot be generated directly"); | ||
720 | default: | 875 | default: |
721 | fatal("key_generate: unknown type %d", type); | 876 | fatal("key_generate: unknown type %d", type); |
722 | } | 877 | } |
@@ -724,12 +879,55 @@ key_generate(int type, u_int bits) | |||
724 | return k; | 879 | return k; |
725 | } | 880 | } |
726 | 881 | ||
882 | void | ||
883 | key_cert_copy(const Key *from_key, struct Key *to_key) | ||
884 | { | ||
885 | u_int i; | ||
886 | const struct KeyCert *from; | ||
887 | struct KeyCert *to; | ||
888 | |||
889 | if (to_key->cert != NULL) { | ||
890 | cert_free(to_key->cert); | ||
891 | to_key->cert = NULL; | ||
892 | } | ||
893 | |||
894 | if ((from = from_key->cert) == NULL) | ||
895 | return; | ||
896 | |||
897 | to = to_key->cert = cert_new(); | ||
898 | |||
899 | buffer_append(&to->certblob, buffer_ptr(&from->certblob), | ||
900 | buffer_len(&from->certblob)); | ||
901 | |||
902 | buffer_append(&to->constraints, buffer_ptr(&from->constraints), | ||
903 | buffer_len(&from->constraints)); | ||
904 | |||
905 | to->type = from->type; | ||
906 | to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id); | ||
907 | to->valid_after = from->valid_after; | ||
908 | to->valid_before = from->valid_before; | ||
909 | to->signature_key = from->signature_key == NULL ? | ||
910 | NULL : key_from_private(from->signature_key); | ||
911 | |||
912 | to->nprincipals = from->nprincipals; | ||
913 | if (to->nprincipals > CERT_MAX_PRINCIPALS) | ||
914 | fatal("%s: nprincipals (%u) > CERT_MAX_PRINCIPALS (%u)", | ||
915 | __func__, to->nprincipals, CERT_MAX_PRINCIPALS); | ||
916 | if (to->nprincipals > 0) { | ||
917 | to->principals = xcalloc(from->nprincipals, | ||
918 | sizeof(*to->principals)); | ||
919 | for (i = 0; i < to->nprincipals; i++) | ||
920 | to->principals[i] = xstrdup(from->principals[i]); | ||
921 | } | ||
922 | } | ||
923 | |||
727 | Key * | 924 | Key * |
728 | key_from_private(const Key *k) | 925 | key_from_private(const Key *k) |
729 | { | 926 | { |
730 | Key *n = NULL; | 927 | Key *n = NULL; |
731 | switch (k->type) { | 928 | switch (k->type) { |
732 | case KEY_DSA: | 929 | case KEY_DSA: |
930 | case KEY_DSA_CERT: | ||
733 | n = key_new(k->type); | 931 | n = key_new(k->type); |
734 | if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || | 932 | if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || |
735 | (BN_copy(n->dsa->q, k->dsa->q) == NULL) || | 933 | (BN_copy(n->dsa->q, k->dsa->q) == NULL) || |
@@ -739,6 +937,7 @@ key_from_private(const Key *k) | |||
739 | break; | 937 | break; |
740 | case KEY_RSA: | 938 | case KEY_RSA: |
741 | case KEY_RSA1: | 939 | case KEY_RSA1: |
940 | case KEY_RSA_CERT: | ||
742 | n = key_new(k->type); | 941 | n = key_new(k->type); |
743 | if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || | 942 | if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || |
744 | (BN_copy(n->rsa->e, k->rsa->e) == NULL)) | 943 | (BN_copy(n->rsa->e, k->rsa->e) == NULL)) |
@@ -748,6 +947,8 @@ key_from_private(const Key *k) | |||
748 | fatal("key_from_private: unknown type %d", k->type); | 947 | fatal("key_from_private: unknown type %d", k->type); |
749 | break; | 948 | break; |
750 | } | 949 | } |
950 | if (key_is_cert(k)) | ||
951 | key_cert_copy(k, n); | ||
751 | return n; | 952 | return n; |
752 | } | 953 | } |
753 | 954 | ||
@@ -764,6 +965,10 @@ key_type_from_name(char *name) | |||
764 | return KEY_RSA; | 965 | return KEY_RSA; |
765 | } else if (strcmp(name, "ssh-dss") == 0) { | 966 | } else if (strcmp(name, "ssh-dss") == 0) { |
766 | return KEY_DSA; | 967 | return KEY_DSA; |
968 | } else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) { | ||
969 | return KEY_RSA_CERT; | ||
970 | } else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) { | ||
971 | return KEY_DSA_CERT; | ||
767 | } else if (strcmp(name, "null") == 0) { | 972 | } else if (strcmp(name, "null") == 0) { |
768 | return KEY_NULL; | 973 | return KEY_NULL; |
769 | } | 974 | } |
@@ -793,6 +998,127 @@ key_names_valid2(const char *names) | |||
793 | return 1; | 998 | return 1; |
794 | } | 999 | } |
795 | 1000 | ||
1001 | static int | ||
1002 | cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | ||
1003 | { | ||
1004 | u_char *principals, *constraints, *sig_key, *sig; | ||
1005 | u_int signed_len, plen, clen, sklen, slen, kidlen; | ||
1006 | Buffer tmp; | ||
1007 | char *principal; | ||
1008 | int ret = -1; | ||
1009 | |||
1010 | buffer_init(&tmp); | ||
1011 | |||
1012 | /* Copy the entire key blob for verification and later serialisation */ | ||
1013 | buffer_append(&key->cert->certblob, blob, blen); | ||
1014 | |||
1015 | principals = constraints = sig_key = sig = NULL; | ||
1016 | if (buffer_get_int_ret(&key->cert->type, b) != 0 || | ||
1017 | (key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL || | ||
1018 | (principals = buffer_get_string_ret(b, &plen)) == NULL || | ||
1019 | buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || | ||
1020 | buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || | ||
1021 | (constraints = buffer_get_string_ret(b, &clen)) == NULL || | ||
1022 | /* skip nonce */ buffer_get_string_ptr_ret(b, NULL) == NULL || | ||
1023 | /* skip reserved */ buffer_get_string_ptr_ret(b, NULL) == NULL || | ||
1024 | (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) { | ||
1025 | error("%s: parse error", __func__); | ||
1026 | goto out; | ||
1027 | } | ||
1028 | |||
1029 | if (kidlen != strlen(key->cert->key_id)) { | ||
1030 | error("%s: key ID contains \\0 character", __func__); | ||
1031 | goto out; | ||
1032 | } | ||
1033 | |||
1034 | /* Signature is left in the buffer so we can calculate this length */ | ||
1035 | signed_len = buffer_len(&key->cert->certblob) - buffer_len(b); | ||
1036 | |||
1037 | if ((sig = buffer_get_string_ret(b, &slen)) == NULL) { | ||
1038 | error("%s: parse error", __func__); | ||
1039 | goto out; | ||
1040 | } | ||
1041 | |||
1042 | if (key->cert->type != SSH2_CERT_TYPE_USER && | ||
1043 | key->cert->type != SSH2_CERT_TYPE_HOST) { | ||
1044 | error("Unknown certificate type %u", key->cert->type); | ||
1045 | goto out; | ||
1046 | } | ||
1047 | |||
1048 | buffer_append(&tmp, principals, plen); | ||
1049 | while (buffer_len(&tmp) > 0) { | ||
1050 | if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) { | ||
1051 | error("%s: Too many principals", __func__); | ||
1052 | goto out; | ||
1053 | } | ||
1054 | if ((principal = buffer_get_string_ret(&tmp, &plen)) == NULL) { | ||
1055 | error("%s: Principals data invalid", __func__); | ||
1056 | goto out; | ||
1057 | } | ||
1058 | if (strlen(principal) != plen) { | ||
1059 | error("%s: Principal contains \\0 character", | ||
1060 | __func__); | ||
1061 | goto out; | ||
1062 | } | ||
1063 | key->cert->principals = xrealloc(key->cert->principals, | ||
1064 | key->cert->nprincipals + 1, sizeof(*key->cert->principals)); | ||
1065 | key->cert->principals[key->cert->nprincipals++] = principal; | ||
1066 | } | ||
1067 | |||
1068 | buffer_clear(&tmp); | ||
1069 | |||
1070 | buffer_append(&key->cert->constraints, constraints, clen); | ||
1071 | buffer_append(&tmp, constraints, clen); | ||
1072 | /* validate structure */ | ||
1073 | while (buffer_len(&tmp) != 0) { | ||
1074 | if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || | ||
1075 | buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { | ||
1076 | error("%s: Constraints data invalid", __func__); | ||
1077 | goto out; | ||
1078 | } | ||
1079 | } | ||
1080 | buffer_clear(&tmp); | ||
1081 | |||
1082 | if ((key->cert->signature_key = key_from_blob(sig_key, | ||
1083 | sklen)) == NULL) { | ||
1084 | error("%s: Signature key invalid", __func__); | ||
1085 | goto out; | ||
1086 | } | ||
1087 | if (key->cert->signature_key->type != KEY_RSA && | ||
1088 | key->cert->signature_key->type != KEY_DSA) { | ||
1089 | error("%s: Invalid signature key type %s (%d)", __func__, | ||
1090 | key_type(key->cert->signature_key), | ||
1091 | key->cert->signature_key->type); | ||
1092 | goto out; | ||
1093 | } | ||
1094 | |||
1095 | switch (key_verify(key->cert->signature_key, sig, slen, | ||
1096 | buffer_ptr(&key->cert->certblob), signed_len)) { | ||
1097 | case 1: | ||
1098 | ret = 0; | ||
1099 | break; /* Good signature */ | ||
1100 | case 0: | ||
1101 | error("%s: Invalid signature on certificate", __func__); | ||
1102 | goto out; | ||
1103 | case -1: | ||
1104 | error("%s: Certificate signature verification failed", | ||
1105 | __func__); | ||
1106 | goto out; | ||
1107 | } | ||
1108 | |||
1109 | out: | ||
1110 | buffer_free(&tmp); | ||
1111 | if (principals != NULL) | ||
1112 | xfree(principals); | ||
1113 | if (constraints != NULL) | ||
1114 | xfree(constraints); | ||
1115 | if (sig_key != NULL) | ||
1116 | xfree(sig_key); | ||
1117 | if (sig != NULL) | ||
1118 | xfree(sig); | ||
1119 | return ret; | ||
1120 | } | ||
1121 | |||
796 | Key * | 1122 | Key * |
797 | key_from_blob(const u_char *blob, u_int blen) | 1123 | key_from_blob(const u_char *blob, u_int blen) |
798 | { | 1124 | { |
@@ -815,10 +1141,12 @@ key_from_blob(const u_char *blob, u_int blen) | |||
815 | 1141 | ||
816 | switch (type) { | 1142 | switch (type) { |
817 | case KEY_RSA: | 1143 | case KEY_RSA: |
1144 | case KEY_RSA_CERT: | ||
818 | key = key_new(type); | 1145 | key = key_new(type); |
819 | if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 || | 1146 | if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 || |
820 | buffer_get_bignum2_ret(&b, key->rsa->n) == -1) { | 1147 | buffer_get_bignum2_ret(&b, key->rsa->n) == -1) { |
821 | error("key_from_blob: can't read rsa key"); | 1148 | error("key_from_blob: can't read rsa key"); |
1149 | badkey: | ||
822 | key_free(key); | 1150 | key_free(key); |
823 | key = NULL; | 1151 | key = NULL; |
824 | goto out; | 1152 | goto out; |
@@ -828,15 +1156,14 @@ key_from_blob(const u_char *blob, u_int blen) | |||
828 | #endif | 1156 | #endif |
829 | break; | 1157 | break; |
830 | case KEY_DSA: | 1158 | case KEY_DSA: |
1159 | case KEY_DSA_CERT: | ||
831 | key = key_new(type); | 1160 | key = key_new(type); |
832 | if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 || | 1161 | if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 || |
833 | buffer_get_bignum2_ret(&b, key->dsa->q) == -1 || | 1162 | buffer_get_bignum2_ret(&b, key->dsa->q) == -1 || |
834 | buffer_get_bignum2_ret(&b, key->dsa->g) == -1 || | 1163 | buffer_get_bignum2_ret(&b, key->dsa->g) == -1 || |
835 | buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) { | 1164 | buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) { |
836 | error("key_from_blob: can't read dsa key"); | 1165 | error("key_from_blob: can't read dsa key"); |
837 | key_free(key); | 1166 | goto badkey; |
838 | key = NULL; | ||
839 | goto out; | ||
840 | } | 1167 | } |
841 | #ifdef DEBUG_PK | 1168 | #ifdef DEBUG_PK |
842 | DSA_print_fp(stderr, key->dsa, 8); | 1169 | DSA_print_fp(stderr, key->dsa, 8); |
@@ -849,6 +1176,10 @@ key_from_blob(const u_char *blob, u_int blen) | |||
849 | error("key_from_blob: cannot handle type %s", ktype); | 1176 | error("key_from_blob: cannot handle type %s", ktype); |
850 | goto out; | 1177 | goto out; |
851 | } | 1178 | } |
1179 | if (key_is_cert(key) && cert_parse(&b, key, blob, blen) == -1) { | ||
1180 | error("key_from_blob: can't parse cert data"); | ||
1181 | goto badkey; | ||
1182 | } | ||
852 | rlen = buffer_len(&b); | 1183 | rlen = buffer_len(&b); |
853 | if (key != NULL && rlen != 0) | 1184 | if (key != NULL && rlen != 0) |
854 | error("key_from_blob: remaining bytes in key blob %d", rlen); | 1185 | error("key_from_blob: remaining bytes in key blob %d", rlen); |
@@ -871,6 +1202,12 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp) | |||
871 | } | 1202 | } |
872 | buffer_init(&b); | 1203 | buffer_init(&b); |
873 | switch (key->type) { | 1204 | switch (key->type) { |
1205 | case KEY_DSA_CERT: | ||
1206 | case KEY_RSA_CERT: | ||
1207 | /* Use the existing blob */ | ||
1208 | buffer_append(&b, buffer_ptr(&key->cert->certblob), | ||
1209 | buffer_len(&key->cert->certblob)); | ||
1210 | break; | ||
874 | case KEY_DSA: | 1211 | case KEY_DSA: |
875 | buffer_put_cstring(&b, key_ssh_name(key)); | 1212 | buffer_put_cstring(&b, key_ssh_name(key)); |
876 | buffer_put_bignum2(&b, key->dsa->p); | 1213 | buffer_put_bignum2(&b, key->dsa->p); |
@@ -907,8 +1244,10 @@ key_sign( | |||
907 | const u_char *data, u_int datalen) | 1244 | const u_char *data, u_int datalen) |
908 | { | 1245 | { |
909 | switch (key->type) { | 1246 | switch (key->type) { |
1247 | case KEY_DSA_CERT: | ||
910 | case KEY_DSA: | 1248 | case KEY_DSA: |
911 | return ssh_dss_sign(key, sigp, lenp, data, datalen); | 1249 | return ssh_dss_sign(key, sigp, lenp, data, datalen); |
1250 | case KEY_RSA_CERT: | ||
912 | case KEY_RSA: | 1251 | case KEY_RSA: |
913 | return ssh_rsa_sign(key, sigp, lenp, data, datalen); | 1252 | return ssh_rsa_sign(key, sigp, lenp, data, datalen); |
914 | default: | 1253 | default: |
@@ -931,8 +1270,10 @@ key_verify( | |||
931 | return -1; | 1270 | return -1; |
932 | 1271 | ||
933 | switch (key->type) { | 1272 | switch (key->type) { |
1273 | case KEY_DSA_CERT: | ||
934 | case KEY_DSA: | 1274 | case KEY_DSA: |
935 | return ssh_dss_verify(key, signature, signaturelen, data, datalen); | 1275 | return ssh_dss_verify(key, signature, signaturelen, data, datalen); |
1276 | case KEY_RSA_CERT: | ||
936 | case KEY_RSA: | 1277 | case KEY_RSA: |
937 | return ssh_rsa_verify(key, signature, signaturelen, data, datalen); | 1278 | return ssh_rsa_verify(key, signature, signaturelen, data, datalen); |
938 | default: | 1279 | default: |
@@ -954,6 +1295,9 @@ key_demote(const Key *k) | |||
954 | pk->rsa = NULL; | 1295 | pk->rsa = NULL; |
955 | 1296 | ||
956 | switch (k->type) { | 1297 | switch (k->type) { |
1298 | case KEY_RSA_CERT: | ||
1299 | key_cert_copy(k, pk); | ||
1300 | /* FALLTHROUGH */ | ||
957 | case KEY_RSA1: | 1301 | case KEY_RSA1: |
958 | case KEY_RSA: | 1302 | case KEY_RSA: |
959 | if ((pk->rsa = RSA_new()) == NULL) | 1303 | if ((pk->rsa = RSA_new()) == NULL) |
@@ -963,6 +1307,9 @@ key_demote(const Key *k) | |||
963 | if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) | 1307 | if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) |
964 | fatal("key_demote: BN_dup failed"); | 1308 | fatal("key_demote: BN_dup failed"); |
965 | break; | 1309 | break; |
1310 | case KEY_DSA_CERT: | ||
1311 | key_cert_copy(k, pk); | ||
1312 | /* FALLTHROUGH */ | ||
966 | case KEY_DSA: | 1313 | case KEY_DSA: |
967 | if ((pk->dsa = DSA_new()) == NULL) | 1314 | if ((pk->dsa = DSA_new()) == NULL) |
968 | fatal("key_demote: DSA_new failed"); | 1315 | fatal("key_demote: DSA_new failed"); |
@@ -982,3 +1329,199 @@ key_demote(const Key *k) | |||
982 | 1329 | ||
983 | return (pk); | 1330 | return (pk); |
984 | } | 1331 | } |
1332 | |||
1333 | int | ||
1334 | key_is_cert(const Key *k) | ||
1335 | { | ||
1336 | return k != NULL && | ||
1337 | (k->type == KEY_RSA_CERT || k->type == KEY_DSA_CERT); | ||
1338 | } | ||
1339 | |||
1340 | /* Return the cert-less equivalent to a certified key type */ | ||
1341 | int | ||
1342 | key_type_plain(int type) | ||
1343 | { | ||
1344 | switch (type) { | ||
1345 | case KEY_RSA_CERT: | ||
1346 | return KEY_RSA; | ||
1347 | case KEY_DSA_CERT: | ||
1348 | return KEY_DSA; | ||
1349 | default: | ||
1350 | return type; | ||
1351 | } | ||
1352 | } | ||
1353 | |||
1354 | /* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */ | ||
1355 | int | ||
1356 | key_to_certified(Key *k) | ||
1357 | { | ||
1358 | switch (k->type) { | ||
1359 | case KEY_RSA: | ||
1360 | k->cert = cert_new(); | ||
1361 | k->type = KEY_RSA_CERT; | ||
1362 | return 0; | ||
1363 | case KEY_DSA: | ||
1364 | k->cert = cert_new(); | ||
1365 | k->type = KEY_DSA_CERT; | ||
1366 | return 0; | ||
1367 | default: | ||
1368 | error("%s: key has incorrect type %s", __func__, key_type(k)); | ||
1369 | return -1; | ||
1370 | } | ||
1371 | } | ||
1372 | |||
1373 | /* Convert a KEY_RSA_CERT or KEY_DSA_CERT to their raw key equivalent */ | ||
1374 | int | ||
1375 | key_drop_cert(Key *k) | ||
1376 | { | ||
1377 | switch (k->type) { | ||
1378 | case KEY_RSA_CERT: | ||
1379 | cert_free(k->cert); | ||
1380 | k->type = KEY_RSA; | ||
1381 | return 0; | ||
1382 | case KEY_DSA_CERT: | ||
1383 | cert_free(k->cert); | ||
1384 | k->type = KEY_DSA; | ||
1385 | return 0; | ||
1386 | default: | ||
1387 | error("%s: key has incorrect type %s", __func__, key_type(k)); | ||
1388 | return -1; | ||
1389 | } | ||
1390 | } | ||
1391 | |||
1392 | /* Sign a KEY_RSA_CERT or KEY_DSA_CERT, (re-)generating the signed certblob */ | ||
1393 | int | ||
1394 | key_certify(Key *k, Key *ca) | ||
1395 | { | ||
1396 | Buffer principals; | ||
1397 | u_char *ca_blob, *sig_blob, nonce[32]; | ||
1398 | u_int i, ca_len, sig_len; | ||
1399 | |||
1400 | if (k->cert == NULL) { | ||
1401 | error("%s: key lacks cert info", __func__); | ||
1402 | return -1; | ||
1403 | } | ||
1404 | |||
1405 | if (!key_is_cert(k)) { | ||
1406 | error("%s: certificate has unknown type %d", __func__, | ||
1407 | k->cert->type); | ||
1408 | return -1; | ||
1409 | } | ||
1410 | |||
1411 | if (ca->type != KEY_RSA && ca->type != KEY_DSA) { | ||
1412 | error("%s: CA key has unsupported type %s", __func__, | ||
1413 | key_type(ca)); | ||
1414 | return -1; | ||
1415 | } | ||
1416 | |||
1417 | key_to_blob(ca, &ca_blob, &ca_len); | ||
1418 | |||
1419 | buffer_clear(&k->cert->certblob); | ||
1420 | buffer_put_cstring(&k->cert->certblob, key_ssh_name(k)); | ||
1421 | |||
1422 | switch (k->type) { | ||
1423 | case KEY_DSA_CERT: | ||
1424 | buffer_put_bignum2(&k->cert->certblob, k->dsa->p); | ||
1425 | buffer_put_bignum2(&k->cert->certblob, k->dsa->q); | ||
1426 | buffer_put_bignum2(&k->cert->certblob, k->dsa->g); | ||
1427 | buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key); | ||
1428 | break; | ||
1429 | case KEY_RSA_CERT: | ||
1430 | buffer_put_bignum2(&k->cert->certblob, k->rsa->e); | ||
1431 | buffer_put_bignum2(&k->cert->certblob, k->rsa->n); | ||
1432 | break; | ||
1433 | default: | ||
1434 | error("%s: key has incorrect type %s", __func__, key_type(k)); | ||
1435 | buffer_clear(&k->cert->certblob); | ||
1436 | xfree(ca_blob); | ||
1437 | return -1; | ||
1438 | } | ||
1439 | |||
1440 | buffer_put_int(&k->cert->certblob, k->cert->type); | ||
1441 | buffer_put_cstring(&k->cert->certblob, k->cert->key_id); | ||
1442 | |||
1443 | buffer_init(&principals); | ||
1444 | for (i = 0; i < k->cert->nprincipals; i++) | ||
1445 | buffer_put_cstring(&principals, k->cert->principals[i]); | ||
1446 | buffer_put_string(&k->cert->certblob, buffer_ptr(&principals), | ||
1447 | buffer_len(&principals)); | ||
1448 | buffer_free(&principals); | ||
1449 | |||
1450 | buffer_put_int64(&k->cert->certblob, k->cert->valid_after); | ||
1451 | buffer_put_int64(&k->cert->certblob, k->cert->valid_before); | ||
1452 | buffer_put_string(&k->cert->certblob, | ||
1453 | buffer_ptr(&k->cert->constraints), | ||
1454 | buffer_len(&k->cert->constraints)); | ||
1455 | |||
1456 | arc4random_buf(&nonce, sizeof(nonce)); | ||
1457 | buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); | ||
1458 | buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */ | ||
1459 | buffer_put_string(&k->cert->certblob, ca_blob, ca_len); | ||
1460 | xfree(ca_blob); | ||
1461 | |||
1462 | /* Sign the whole mess */ | ||
1463 | if (key_sign(ca, &sig_blob, &sig_len, buffer_ptr(&k->cert->certblob), | ||
1464 | buffer_len(&k->cert->certblob)) != 0) { | ||
1465 | error("%s: signature operation failed", __func__); | ||
1466 | buffer_clear(&k->cert->certblob); | ||
1467 | return -1; | ||
1468 | } | ||
1469 | /* Append signature and we are done */ | ||
1470 | buffer_put_string(&k->cert->certblob, sig_blob, sig_len); | ||
1471 | xfree(sig_blob); | ||
1472 | |||
1473 | return 0; | ||
1474 | } | ||
1475 | |||
1476 | int | ||
1477 | key_cert_check_authority(const Key *k, int want_host, int require_principal, | ||
1478 | const char *name, const char **reason) | ||
1479 | { | ||
1480 | u_int i, principal_matches; | ||
1481 | time_t now = time(NULL); | ||
1482 | |||
1483 | if (want_host) { | ||
1484 | if (k->cert->type != SSH2_CERT_TYPE_HOST) { | ||
1485 | *reason = "Certificate invalid: not a host certificate"; | ||
1486 | return -1; | ||
1487 | } | ||
1488 | } else { | ||
1489 | if (k->cert->type != SSH2_CERT_TYPE_USER) { | ||
1490 | *reason = "Certificate invalid: not a user certificate"; | ||
1491 | return -1; | ||
1492 | } | ||
1493 | } | ||
1494 | if (now < 0) { | ||
1495 | error("%s: system clock lies before epoch", __func__); | ||
1496 | *reason = "Certificate invalid: not yet valid"; | ||
1497 | return -1; | ||
1498 | } | ||
1499 | if ((u_int64_t)now < k->cert->valid_after) { | ||
1500 | *reason = "Certificate invalid: not yet valid"; | ||
1501 | return -1; | ||
1502 | } | ||
1503 | if ((u_int64_t)now >= k->cert->valid_before) { | ||
1504 | *reason = "Certificate invalid: expired"; | ||
1505 | return -1; | ||
1506 | } | ||
1507 | if (k->cert->nprincipals == 0) { | ||
1508 | if (require_principal) { | ||
1509 | *reason = "Certificate lacks principal list"; | ||
1510 | return -1; | ||
1511 | } | ||
1512 | } else { | ||
1513 | principal_matches = 0; | ||
1514 | for (i = 0; i < k->cert->nprincipals; i++) { | ||
1515 | if (strcmp(name, k->cert->principals[i]) == 0) { | ||
1516 | principal_matches = 1; | ||
1517 | break; | ||
1518 | } | ||
1519 | } | ||
1520 | if (!principal_matches) { | ||
1521 | *reason = "Certificate invalid: name is not a listed " | ||
1522 | "principal"; | ||
1523 | return -1; | ||
1524 | } | ||
1525 | } | ||
1526 | return 0; | ||
1527 | } | ||