|
|
3a67ab |
diff --git a/security/pkix/lib/pkixder.cpp b/security/pkix/lib/pkixder.cpp
|
|
|
3a67ab |
--- a/security/pkix/lib/pkixder.cpp
|
|
|
3a67ab |
+++ b/security/pkix/lib/pkixder.cpp
|
|
|
3a67ab |
@@ -466,28 +466,63 @@ TimeChoice(Reader& tagged, uint8_t expec
|
|
|
3a67ab |
if (rv != Success) {
|
|
|
3a67ab |
return rv;
|
|
|
3a67ab |
}
|
|
|
3a67ab |
|
|
|
3a67ab |
uint8_t b;
|
|
|
3a67ab |
if (input.Read(b) != Success) {
|
|
|
3a67ab |
return Result::ERROR_INVALID_DER_TIME;
|
|
|
3a67ab |
}
|
|
|
3a67ab |
- if (b != 'Z') {
|
|
|
3a67ab |
+
|
|
|
3a67ab |
+ unsigned int hourOffset = 0;
|
|
|
3a67ab |
+ unsigned int minuteOffset = 0;
|
|
|
3a67ab |
+ bool allowOffset = false;
|
|
|
3a67ab |
+ bool haveOffset = false;
|
|
|
3a67ab |
+ bool offsetIsPositive = false;
|
|
|
3a67ab |
+
|
|
|
3a67ab |
+ if (getenv("PKIX_ALLOW_CERT_UTCTIME_OFFSET") != 0) {
|
|
|
3a67ab |
+ allowOffset = true;
|
|
|
3a67ab |
+ }
|
|
|
3a67ab |
+
|
|
|
3a67ab |
+ if (allowOffset && (b == '+' || b == '-')) {
|
|
|
3a67ab |
+ haveOffset = true;
|
|
|
3a67ab |
+ rv = ReadTwoDigits(input, 0u, 23u, hourOffset);
|
|
|
3a67ab |
+ if (rv != Success) {
|
|
|
3a67ab |
+ return rv;
|
|
|
3a67ab |
+ }
|
|
|
3a67ab |
+ rv = ReadTwoDigits(input, 0u, 59u, minuteOffset);
|
|
|
3a67ab |
+ if (rv != Success) {
|
|
|
3a67ab |
+ return rv;
|
|
|
3a67ab |
+ }
|
|
|
3a67ab |
+ if (b == '+') {
|
|
|
3a67ab |
+ offsetIsPositive = true;
|
|
|
3a67ab |
+ }
|
|
|
3a67ab |
+ } else if (b != 'Z') {
|
|
|
3a67ab |
return Result::ERROR_INVALID_DER_TIME;
|
|
|
3a67ab |
}
|
|
|
3a67ab |
if (End(input) != Success) {
|
|
|
3a67ab |
return Result::ERROR_INVALID_DER_TIME;
|
|
|
3a67ab |
}
|
|
|
3a67ab |
|
|
|
3a67ab |
uint64_t totalSeconds = (static_cast<uint64_t>(days) * 24u * 60u * 60u) +
|
|
|
3a67ab |
(static_cast<uint64_t>(hours) * 60u * 60u) +
|
|
|
3a67ab |
(static_cast<uint64_t>(minutes) * 60u) +
|
|
|
3a67ab |
seconds;
|
|
|
3a67ab |
|
|
|
3a67ab |
+ if (haveOffset) {
|
|
|
3a67ab |
+ uint64_t offsetInSeconds =
|
|
|
3a67ab |
+ (static_cast<uint64_t>(hourOffset) * 60u * 60u) +
|
|
|
3a67ab |
+ (static_cast<uint64_t>(minuteOffset) * 60u);
|
|
|
3a67ab |
+ if (offsetIsPositive) {
|
|
|
3a67ab |
+ totalSeconds -= offsetInSeconds;
|
|
|
3a67ab |
+ } else {
|
|
|
3a67ab |
+ totalSeconds += offsetInSeconds;
|
|
|
3a67ab |
+ }
|
|
|
3a67ab |
+ }
|
|
|
3a67ab |
+
|
|
|
3a67ab |
time = TimeFromElapsedSecondsAD(totalSeconds);
|
|
|
3a67ab |
return Success;
|
|
|
3a67ab |
}
|
|
|
3a67ab |
|
|
|
3a67ab |
Result
|
|
|
3a67ab |
IntegralBytes(Reader& input, uint8_t tag,
|
|
|
3a67ab |
IntegralValueRestriction valueRestriction,
|
|
|
3a67ab |
/*out*/ Input& value,
|