namemap alias handling causes providers to conflict with each other #23369
Replies: 2 comments 4 replies
-
This is not a bug. This was a conscious design decision. I'll let @levitte and @mattcaswell to explain why this design decision was made but I do not think this should be changed at this point. |
Beta Was this translation helpful? Give feedback.
-
The assumption we made, quite early on, was that all algorithm names are global and that aliases exist. So re global names, you can't have RSA and RSA being two completely different algorithms, for example. The implementations might differ a bit, but on a primitive level, they are assumed to be the same... Furthermore, re aliases, this is partly due to this already being present in pre-3.0 OpenSSL (see things like { "RSA", "provider=default", ossl_rsa_signature_functions },
{ "rsaEncryption", "provider=default", ossl_rsa_signature_functions },
{ "1.2.840.113549.1.1.1", "provider=default", ossl_rsa_signature_functions }, However, that doesn't answer the assumed global nature of algorithm names. In the early discussions, we knew there would be exactly this sort of conflict. What we figured was that then there is a conflict, and not just on an implementation level, and that (to take your example), the authors of provider1 and provider2 would have to have a conversation and resolve that conflict. On a very human level, this is akin to two different inventors in the world inventing an algorithm BLARGH (my favorite fictituous algo name), completely different algorithms, and then both approaching NIST, or IETF, or whatever international standardization group. I very much imagine that said group would tell those inventors pretty quickly that, "... er, there's a name conflict, we can't have that". |
Beta Was this translation helpful? Give feedback.
-
I was looking at how provider lookup works in 3.x, and noticed a weird behavior of the namemap machinery.
OpenSSL allows an algorithm to advertise multiple names. However, rather than implementing this directly, it #8967 implemented deep inside the namemap machinery. If provider1 implements an algorithm with names "A" and "B", both "A" and "B" will map to the same number in the namemap.
But the namemap is shared across providers! So if provider2 only names an algorithm "A", suddenly loading provider1 will make "B" also pick up provider2.A! If provider3 thinks "A" and "B" are distinct algorithms, it conflicts and you cannot load provider1 and provider3 at the same time. Whichever is loaded first wins and the other has an error. Moreover, this error is discovered late because of all the lazy-loading machinery. This effect persists even after providers are unloaded. If one loads a provider that links "A" and "B" together, "A" and "B" are forever linked in that context, even after the provider is unloaded.
This doesn't seem like the right behavior. Much more intuitive would be that
EVP_MD_fetch("A")
considers provider1.A, provider2.A, provider3.A, etc., without caring about the other names of those algorithms. That provider1.B happens to be the same object as provider1.A but provider3.B happens to be a distinct object should not matter.This came about because I was curious what it'd take to remove all the mutable caches and switch providers to a simpler and more performant immutable-after-construction design. Having this kind of provider cross-talk makes efficient designs trickier.
Beta Was this translation helpful? Give feedback.
All reactions