diff options
author | beck <> | 2017-05-04 12:36:13 +0000 |
---|---|---|
committer | beck <> | 2017-05-04 12:36:13 +0000 |
commit | a42ca65afd784c6a6f9a4dfbd937482b27c73fc3 (patch) | |
tree | d5d81bf6036760c8798fcf991578a82206ba1b02 | |
parent | 368c36d15560665530746e106272e31a92b3fe41 (diff) | |
download | openbsd-a42ca65afd784c6a6f9a4dfbd937482b27c73fc3.tar.gz openbsd-a42ca65afd784c6a6f9a4dfbd937482b27c73fc3.tar.bz2 openbsd-a42ca65afd784c6a6f9a4dfbd937482b27c73fc3.zip |
Fix the ca command so that certs it generates have RFC5280 conformant time.
Problem noticed by Harald Dunkel <harald.dunkel@aixigo.de>
-rw-r--r-- | src/usr.bin/openssl/ca.c | 72 |
1 files changed, 56 insertions, 16 deletions
diff --git a/src/usr.bin/openssl/ca.c b/src/usr.bin/openssl/ca.c index a3e779da33..9ed7c59caa 100644 --- a/src/usr.bin/openssl/ca.c +++ b/src/usr.bin/openssl/ca.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ca.c,v 1.23 2017/01/20 08:57:11 deraadt Exp $ */ | 1 | /* $OpenBSD: ca.c,v 1.24 2017/05/04 12:36:13 beck Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -207,6 +207,48 @@ static int preserve = 0; | |||
207 | static int msie_hack = 0; | 207 | static int msie_hack = 0; |
208 | 208 | ||
209 | 209 | ||
210 | /* | ||
211 | * Set a certificate time based on user provided input. Make sure | ||
212 | * what we put in the certificate is legit for RFC 5280. Returns | ||
213 | * 0 on success, -1 on an invalid time string. Strings must be | ||
214 | * YYYYMMDDHHMMSSZ for post 2050 dates. YYYYMMDDHHMMSSZ or | ||
215 | * YYMMDDHHMMSSZ is accepted for pre 2050 dates, and fixed up to | ||
216 | * be the correct format in the certificate. | ||
217 | */ | ||
218 | static int | ||
219 | setCertificateTime(ASN1_TIME *x509time, char *timestring) | ||
220 | { | ||
221 | struct tm tm1, tm2; | ||
222 | char *rfctime = timestring; | ||
223 | int type; | ||
224 | |||
225 | memset(&tm1, 0, sizeof(tm1)); | ||
226 | memset(&tm2, 0, sizeof(tm2)); | ||
227 | type = ASN1_time_parse(timestring, strlen(timestring), &tm1, 0); | ||
228 | if (type == -1) { | ||
229 | return (-1); | ||
230 | } | ||
231 | |||
232 | /* RFC 5280 section 4.1.2.5 */ | ||
233 | if (tm1.tm_year < 150 && type != V_ASN1_UTCTIME) { | ||
234 | if (strlen(timestring) == 15) { | ||
235 | /* Fix date if possible */ | ||
236 | rfctime = timestring + 2; | ||
237 | type = ASN1_time_parse(rfctime, strlen(rfctime), | ||
238 | &tm2, 0); | ||
239 | if (type != V_ASN1_UTCTIME || | ||
240 | tm1.tm_year != tm2.tm_year) | ||
241 | return (-1); | ||
242 | } else | ||
243 | return (-1); | ||
244 | } | ||
245 | if (tm1.tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME) | ||
246 | return (-1); | ||
247 | ASN1_TIME_set_string(x509time, rfctime); | ||
248 | return (0); | ||
249 | } | ||
250 | |||
251 | |||
210 | int | 252 | int |
211 | ca_main(int argc, char **argv) | 253 | ca_main(int argc, char **argv) |
212 | { | 254 | { |
@@ -905,10 +947,6 @@ bad: | |||
905 | if (startdate == NULL) | 947 | if (startdate == NULL) |
906 | ERR_clear_error(); | 948 | ERR_clear_error(); |
907 | } | 949 | } |
908 | if (startdate && !ASN1_TIME_set_string(NULL, startdate)) { | ||
909 | BIO_printf(bio_err, "start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n"); | ||
910 | goto err; | ||
911 | } | ||
912 | if (startdate == NULL) | 950 | if (startdate == NULL) |
913 | startdate = "today"; | 951 | startdate = "today"; |
914 | 952 | ||
@@ -918,16 +956,12 @@ bad: | |||
918 | if (enddate == NULL) | 956 | if (enddate == NULL) |
919 | ERR_clear_error(); | 957 | ERR_clear_error(); |
920 | } | 958 | } |
921 | if (enddate && !ASN1_TIME_set_string(NULL, enddate)) { | 959 | if (days == 0 && enddate == NULL) { |
922 | BIO_printf(bio_err, "end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n"); | ||
923 | goto err; | ||
924 | } | ||
925 | if (days == 0) { | ||
926 | if (!NCONF_get_number(conf, section, | 960 | if (!NCONF_get_number(conf, section, |
927 | ENV_DEFAULT_DAYS, &days)) | 961 | ENV_DEFAULT_DAYS, &days)) |
928 | days = 0; | 962 | days = 0; |
929 | } | 963 | } |
930 | if (!enddate && (days == 0)) { | 964 | if (enddate == NULL && days == 0) { |
931 | BIO_printf(bio_err, | 965 | BIO_printf(bio_err, |
932 | "cannot lookup how many days to certify for\n"); | 966 | "cannot lookup how many days to certify for\n"); |
933 | goto err; | 967 | goto err; |
@@ -1774,13 +1808,19 @@ again2: | |||
1774 | 1808 | ||
1775 | if (strcmp(startdate, "today") == 0) | 1809 | if (strcmp(startdate, "today") == 0) |
1776 | X509_gmtime_adj(X509_get_notBefore(ret), 0); | 1810 | X509_gmtime_adj(X509_get_notBefore(ret), 0); |
1777 | else | 1811 | else if (setCertificateTime(X509_get_notBefore(ret), startdate) == -1) { |
1778 | ASN1_TIME_set_string(X509_get_notBefore(ret), startdate); | 1812 | BIO_printf(bio_err, "Invalid start date %s\n", |
1813 | startdate); | ||
1814 | goto err; | ||
1815 | } | ||
1779 | 1816 | ||
1780 | if (enddate == NULL) | 1817 | if (enddate == NULL) |
1781 | X509_time_adj_ex(X509_get_notAfter(ret), days, 0, NULL); | 1818 | X509_time_adj_ex(X509_get_notAfter(ret), days, 0, NULL); |
1782 | else | 1819 | else if (setCertificateTime(X509_get_notAfter(ret), enddate) == -1) { |
1783 | ASN1_TIME_set_string(X509_get_notAfter(ret), enddate); | 1820 | BIO_printf(bio_err, "Invalid end date %s\n", |
1821 | enddate); | ||
1822 | goto err; | ||
1823 | } | ||
1784 | 1824 | ||
1785 | if (!X509_set_subject_name(ret, subject)) | 1825 | if (!X509_set_subject_name(ret, subject)) |
1786 | goto err; | 1826 | goto err; |