Open reox opened 6 years ago
I am a little hesitant to add this, mostly in that certs have subtle elements and there are complex rules for "comparing" them. It probably make sense, however.
Any thoughts @joernheissler, @mttcpr, @tiran?
It should be more generic, not only for certs.
E.g. I took your SignedDigestAlgorithm
:
#!/usr/bin/env python3
from asn1crypto.algos import SignedDigestAlgorithm
alg = bytes.fromhex('300d06092a864886f70d01010b0500')
x = SignedDigestAlgorithm.load(alg)
y = SignedDigestAlgorithm.load(alg)
print(x == y) # False
print(x['algorithm'] == y['algorithm']) # True
print(x['parameters'] == y['parameters']) # True
My expectation is for all those comparisons to be True. Your certs should also be equal.
I'm not entirely sure why they don't. It looks like the intended __eq__
method doesn't run but object.__eq__
is used. Is that caused by inheriting from _ForceNullParameters
?
It gets even more complicated:
from asn1crypto.core import Boolean
a = Boolean.load(b'\x01\x01\xff')
b = Boolean.load(b'\x01\x01\x33')
c = Boolean(True)
a.native # True
b.native # True
c.native # True
a == b # False
b == c # False
a == c # True
My first intuition says that a == b
should be True
as well. Both are True
. But a.dump() != b.dump()
. However, a.dump(True) == b.dump(True)
. And now a == b
is True, which was False before calling dump(True)
.
Existing code might depend on the current behaviour, or it might depend on the expectations of the programmer.
Now about __hash__
: If __eq__
is True, the hash needs to equal too. If the comparison is done based on the encoding (contents attribute), maybe return hash(self.contents)
. If it's based on the actual contents, it would depend on the type. E.g. for a Sequence return hash(self.children)
.
Currently __eq__
is only defined for Primitive values (string, int, bool, etc), not those derived from Sequence or Set. The exception to this is some of the x509
sequences have explicit comparisons defined in the RFCs, so those have been implemented.
The current implementation for primitive values factors in a number of things. You've found one of the edge cases, that is where BER and DER encodings of the same value will not compare equally.
I don't know if it is a good idea to provide a general case comparison for structured types, since that may be defined differently based on the use case. I suppose that if the DER encodings are exactly the same, the values should be able to be considered equal.
From this, I think at the very least we could:
.contents
x509.Certificate
and various structures in algos
and keys
Today I noted, that two certificates from the same bytes would not compare equal to each other. Here is an example:
In my opinion two certificate objects should compare equal to each other if the content is the same. Or is there a reason that two certifictaes does not compare to each other?