Closed urda closed 7 years ago
It looks like the beacon.nist.gov
cert has a Not Valid After
of 2017-05-07T14:18:36+00:00
Timestamp | Epoch as NIST Record Link | Notes |
---|---|---|
2017-05-07T14:18:00+00:00 |
1494166680 |
This could be the last valid record currently |
2017-05-07T14:18:36+00:00 |
1494166716 |
This is the record at the time of Not Valid After on the certificate. |
2017-05-07T14:19:00+00:00 |
1494166740 |
This is the record that is returned by the API given our Not Valid After date |
Timestamp | Output Value | Previous Output Value |
---|---|---|
1494166680 |
29DA3AC0491B296FDCD7FB5433ECEBCF965EA10207D7A33476B1845CE05F8305F23BD38508D59F04C54A1972635A726072CC2E48DF6260951D314388FEEAB088 |
75C85E3EAD2C5F813C596A9EFD9AE4B4D87762C0E707C85293E433B81D20AD92CB7260BCC7E5F0AACE79DC0DBF7C2580D994D861CA5D3236D07503E3AC6E1EB6 |
1494166740 |
01BE623A11E19BA6C4FA9078A531FBE74B71AA8D64A99F1303698DF8B7712F30AB689AE92E6ADDD45D1155542DF0C9E5B2748B09286CB0A4EF19B47B726522E9 |
29DA3AC0491B296FDCD7FB5433ECEBCF965EA10207D7A33476B1845CE05F8305F23BD38508D59F04C54A1972635A726072CC2E48DF6260951D314388FEEAB088 |
As expected, record 1494166740
points to 1494166680
In [1]: from nistbeacon import NistBeacon
In [2]: record_1494166680 = NistBeacon.get_record(1494166680)
In [3]: record_1494166740 = NistBeacon.get_record(1494166740)
In [4]: record_1494166680.valid_signature
Out[4]: True
In [5]: record_1494166740.valid_signature
Out[5]: True
In [6]: record_1494166800 = NistBeacon.get_record(1494166800)
In [7]: record_1494166800.valid_signature
Out[7]: True
I expected record 1494166740
to demonstrate the current problem. I'll have to dig a bit deeper for now.
python
to find the failure boundary#!/usr/bin/env python
from nistbeacon import NistBeacon
def seek_boundary(timestamp: int):
max_fails = 60
fail_count = 0
record = NistBeacon.get_record(timestamp)
while fail_count < max_fails:
# Signature check
if type(record.valid_signature) is not bool or not record.valid_signature:
fail_count += 1
# Report record information, and program state
print(
"Timestamp: {0} - "
"valid_signature: {1} - "
"type(valid_signature): {2} - "
"fail_count: {3}".format(
record.timestamp,
record.valid_signature,
type(record.valid_signature),
fail_count,
)
)
# Advance our timestamp pointer
record = NistBeacon.get_next(record.timestamp)
print("Maximum failures reached. Stopping.")
if __name__ == '__main__':
seek_boundary(1495836840)
python
program output:$ ./find_fail.py
Timestamp: 1495836840 - valid_signature: True - type(valid_signature): <class 'bool'> - fail_count: 0
Timestamp: 1495836900 - valid_signature: True - type(valid_signature): <class 'bool'> - fail_count: 0
Timestamp: 1495836960 - valid_signature: True - type(valid_signature): <class 'bool'> - fail_count: 0
Timestamp: 1495837080 - valid_signature: True - type(valid_signature): <class 'bool'> - fail_count: 0
Timestamp: 1496176860 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 1
Timestamp: 1496176920 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 2
Timestamp: 1496176980 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 3
Timestamp: 1496177040 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 4
Timestamp: 1496177100 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 5
Timestamp: 1496177160 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 6
Timestamp: 1496177220 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 7
Timestamp: 1496177280 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 8
Timestamp: 1496177340 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 9
Timestamp: 1496177400 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 10
Timestamp: 1496177460 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 11
Timestamp: 1496177520 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 12
Timestamp: 1496177580 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 13
Timestamp: 1496177640 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 14
Timestamp: 1496177700 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 15
Timestamp: 1496177760 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 16
Timestamp: 1496177820 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 17
Timestamp: 1496177880 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 18
Timestamp: 1496177940 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 19
Timestamp: 1496178000 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 20
Timestamp: 1496178060 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 21
Timestamp: 1496178120 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 22
Timestamp: 1496178180 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 23
Timestamp: 1496178240 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 24
Timestamp: 1496178300 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 25
Timestamp: 1496178360 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 26
Timestamp: 1496178420 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 27
Timestamp: 1496178480 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 28
Timestamp: 1496178540 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 29
Timestamp: 1496178600 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 30
Timestamp: 1496178660 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 31
Timestamp: 1496178720 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 32
Timestamp: 1496178780 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 33
Timestamp: 1496178840 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 34
Timestamp: 1496178900 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 35
Timestamp: 1496178960 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 36
Timestamp: 1496179020 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 37
Timestamp: 1496179080 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 38
Timestamp: 1496179140 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 39
Timestamp: 1496179200 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 40
Timestamp: 1496179260 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 41
Timestamp: 1496179320 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 42
Timestamp: 1496179380 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 43
Timestamp: 1496179440 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 44
Timestamp: 1496179500 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 45
Timestamp: 1496179560 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 46
Timestamp: 1496179620 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 47
Timestamp: 1496179680 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 48
Timestamp: 1496179740 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 49
Timestamp: 1496179800 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 50
Timestamp: 1496179860 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 51
Timestamp: 1496179920 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 52
Timestamp: 1496179980 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 53
Timestamp: 1496180040 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 54
Timestamp: 1496180100 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 55
Timestamp: 1496180160 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 56
Timestamp: 1496180220 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 57
Timestamp: 1496180280 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 58
Timestamp: 1496180340 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 59
Timestamp: 1496180400 - valid_signature: 0 - type(valid_signature): <class 'int'> - fail_count: 60
Maximum failures reached. Stopping.
1495836840
?I was using the API to perform a binary search to determine where the failures started. Eventually, 1495836840
got me close enough to determine the problem area.
Epoch | Timestamp | valid_signature value |
valid_signature type |
---|---|---|---|
1495837080 |
Friday, 26-May-17 22:18:00 UTC |
True |
<class 'bool'> |
1496176860 |
Tuesday, 30-May-17 20:41:00 UTC |
0 |
<class 'int'> |
Looks like there was a window of downtime. But 1495837080
is well after the Not Valid After
date. Hm.
It looks like the signature_value
has dropped from a length of 512
to 256
.
I can safely determine this is not because of the expired certificate, but NIST has changed how signatures are computed at this time.
@urda Did you ever determine what the cause of the drop of signature_value
length from 512
to 256
was caused by? I'd love to be able to implement a workaround to validate signatures after 1495837080
Hi @grempe !
I'm still engaged with NIST
at this time regarding this change and their upcoming API changes. I've been hesitant to fully patch out record validation until then. Alas, the best advice I can offer you for now is to either wait for me to push a library update, or provide more information from NIST
as it becomes available to me.
ok, I asked Rene for an update via email just now as well (you were cc). We'll see if there is a response. Thx
@grempe great thanks so much! I was about to ping him again as well.
Hi @urda, FYI, I have implemented the new pubkey.pem file that Rene provided you and I in email, and I am able to verify the old and new block signatures. I've coded it in such a way as to try the new pem key first, and then fallback to trying to verify with the x509 cert if that fails. Only if they both fail will I mark the record with a bad signature.
I believe there is still a segment of blocks from during the recent HSM crash period where they cannot verify with either key. I have not yet walked the whole chain to identify that segment though. Since you already have a script to perform that chain walk perhaps you'll give it a go so we can at least document which block ranges will never verify.
You can take a look over here for my JS lib.
https://github.com/grempe/nist-randomness-beacon
Cheers.
This is my current understanding as I'm working on my library's patch:
Milestone | Timestamp |
---|---|
START ... Original Cert |
1378395540 |
END ..... Original Cert |
1495837080 |
START ... Invalid Signatures |
1496176860 |
END ..... Invalid Signatures |
1502201640 |
START ... New Cert |
1502202360 |
END ..... New Cert |
All records following |
Without doing any research, I imagine all records that fall between the START
and END
of "Invalid Signatures" we will be unable to match due to NIST's bug in record signing.
Means a few things:
START
and END
positions of the known record historyFixed and released.
We should have some type of test or tests that can:
last
good recordnext
(and following) records signed with the expired certificate.Why?
To determine how the library is currently behaving with these signed, but invalid records being reported by NIST. This will allow us to:
Not Valid After
value is causing these problems