Get the apr time (micro seconds, since 1970) from an ASN1 time, as stored in X509 * certificates. OpenSSL now has a utility function, but other *SSL derivatives have * not caught up yet or chose to ignore. An alternative is implemented, we prefer * however the *SSL to maintain such things. */
| 210 | * however the *SSL to maintain such things. |
| 211 | */ |
| 212 | static apr_time_t md_asn1_time_get(const ASN1_TIME* time) |
| 213 | { |
| 214 | #if OPENSSL_VERSION_NUMBER < 0x10002000L || (defined(LIBRESSL_VERSION_NUMBER) && \ |
| 215 | LIBRESSL_VERSION_NUMBER < 0x3060000fL) |
| 216 | /* courtesy: https://stackoverflow.com/questions/10975542/asn1-time-to-time-t-conversion#11263731 |
| 217 | * all bugs are mine */ |
| 218 | apr_time_exp_t t; |
| 219 | apr_time_t ts; |
| 220 | const char* str = (const char*) time->data; |
| 221 | apr_size_t i = 0; |
| 222 | |
| 223 | if ((time->length < 12) || ( |
| 224 | (time->type == V_ASN1_GENERALIZEDTIME) && time->length < 16)) |
| 225 | return 0; |
| 226 | |
| 227 | memset(&t, 0, sizeof(t)); |
| 228 | |
| 229 | if (time->type == V_ASN1_UTCTIME) {/* two digit year */ |
| 230 | t.tm_year = (str[i++] - '0') * 10; |
| 231 | t.tm_year += (str[i++] - '0'); |
| 232 | if (t.tm_year < 70) |
| 233 | t.tm_year += 100; |
| 234 | } |
| 235 | else if (time->type == V_ASN1_GENERALIZEDTIME) {/* four digit year */ |
| 236 | t.tm_year = (str[i++] - '0') * 1000; |
| 237 | t.tm_year+= (str[i++] - '0') * 100; |
| 238 | t.tm_year+= (str[i++] - '0') * 10; |
| 239 | t.tm_year+= (str[i++] - '0'); |
| 240 | t.tm_year -= 1900; |
| 241 | } |
| 242 | t.tm_mon = (str[i++] - '0') * 10; |
| 243 | t.tm_mon += (str[i++] - '0') - 1; /* -1 since January is 0 not 1. */ |
| 244 | t.tm_mday = (str[i++] - '0') * 10; |
| 245 | t.tm_mday+= (str[i++] - '0'); |
| 246 | t.tm_hour = (str[i++] - '0') * 10; |
| 247 | t.tm_hour+= (str[i++] - '0'); |
| 248 | t.tm_min = (str[i++] - '0') * 10; |
| 249 | t.tm_min += (str[i++] - '0'); |
| 250 | t.tm_sec = (str[i++] - '0') * 10; |
| 251 | t.tm_sec += (str[i++] - '0'); |
| 252 | |
| 253 | if (APR_SUCCESS == apr_time_exp_gmt_get(&ts, &t)) { |
| 254 | return ts; |
| 255 | } |
| 256 | return 0; |
| 257 | #else |
| 258 | int secs, days; |
| 259 | apr_time_t ts = apr_time_now(); |
| 260 | |
| 261 | if (ASN1_TIME_diff(&days, &secs, NULL, time)) { |
| 262 | ts += apr_time_from_sec((days * MD_SECS_PER_DAY) + secs); |
| 263 | } |
| 264 | return ts; |
| 265 | #endif |
| 266 | } |
| 267 | |
| 268 | apr_time_t md_asn1_generalized_time_get(void *asn1_gtime) |
| 269 | { |
no outgoing calls
no test coverage detected