Closed
Bug 1044350
Opened 10 years ago
Closed 8 years ago
enum corrupted when calling CheckKeyUsage, https: fails w/ SEC_ERROR_INADEQUATE_KEY_USAGE
Categories
(Core :: Security: PSM, defect)
Tracking
()
RESOLVED
WORKSFORME
People
(Reporter: hcoin, Unassigned)
References
Details
User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0 (Beta/Release) Build ID: 20140608211457 Steps to reproduce: v31 firefox for ubuntu, usual apt-get install firefox. amd64 gdb --args /usr/lib/firefox/firefox Surf to internal website via https: https://internal.site.com CA imported, trusted: X509v3 extensions: X509v3 Subject Key Identifier: C8:2B:09:5C:F3:B5:B4:D2:BB:16:98:77:05:3B:D0:31:49:10:B2:93 X509v3 Key Usage: Certificate Sign, CRL Sign X509v3 Basic Constraints: critical CA:TRUE, pathlen:0 X509v3 CRL Distribution Points: website cert: X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication X509v3 Subject Alternative Name: DNS:www.nottelling.com, DNS:www1.nottelling.com, DNS:dbadmin.nottelling.com, IP Address:192.168.29.253, IP Address:192.168.23.1, IP Address:127.0.0.1 X509v3 Subject Key Identifier: A8:59:22:96:79:0B:3A:55:0A:E1:55:76:D8:A6:92:90:2E:C2:AF:B2 X509v3 Authority Key Identifier: keyid:C8:2B:09:5C:F3:B5:B4:D2:BB:16:98:77:05:3B:D0:31:49:10:B2:93 X509v3 CRL Distribution Points: Full Name: URI:http://www.nottelling.com/ca/myca.crl X509v3 Basic Constraints: critical CA:FALSE --- Firefox always reports: Certificate key usage inadequate for attempted operation. (Error code: sec_error_inadequate_key_usage) Problem didn't happen on v30. Actual results: Watch 'endEntityOrCA' begin life as mozilla::pkix::MustBeEndEntity, but change to mozilla::pkix::MustBeCA | unknown: 1390136216 as it enters CheckKeyUsage. Could it be a compiler error, calling a function in the namespace but not in the instance confuses the variables on the stack? Breakpoint 2, mozilla::pkix::CheckIssuerIndependentProperties (trustDomain=..., cert=..., time=time@entry=1406341186571161, endEntityOrCA=endEntityOrCA@entry=mozilla::pkix::MustBeEndEntity, requiredKeyUsageIfPresent=mozilla::pkix::digitalSignature, requiredEKUIfPresent=requiredEKUIfPresent@entry=SEC_OID_EXT_KEY_USAGE_SERVER_AUTH, requiredPolicy=requiredPolicy@entry=SEC_OID_X509_ANY_POLICY, subCACount=subCACount@entry=0, trustLevelOut=trustLevelOut@entry=0x7fffc02fa54c) at /build/buildd/firefox-31.0+build1/security/pkix/lib/pkixcheck.cpp:603 603 &trustLevel)); (gdb) s 596 { (gdb) n 603 &trustLevel)); (gdb) n 607 if (trustLevel == TrustDomain::ActivelyDistrusted) { (gdb) n 611 if (trustLevel != TrustDomain::TrustAnchor && (gdb) n 617 if (trustLevelOut) { (gdb) n 618 *trustLevelOut = trustLevel; (gdb) n 621 bool isTrustAnchor = endEntityOrCA == MustBeCA && (gdb) n 624 PLArenaPool* arena = cert.GetArena(); (gdb) n 625 if (!arena) { (gdb) p endEntityOrCA $99 = mozilla::pkix::MustBeEndEntity (gdb) n 635 requiredKeyUsageIfPresent); (gdb) p endEntityOrCA $100 = mozilla::pkix::MustBeEndEntity (gdb) s mozilla::pkix::CheckKeyUsage (endEntityOrCA=(mozilla::pkix::MustBeCA | unknown: 1390136216), encodedKeyUsage=0x7fffb3004aa0, requiredKeyUsageIfPresent=requiredKeyUsageIfPresent@entry=mozilla::pkix::digitalSignature) at /build/buildd/firefox-31.0+build1/security/pkix/lib/pkixcheck.cpp:55 55 if (!encodedKeyUsage) { (gdb) p endEntityOrCA $101 = (mozilla::pkix::MustBeCA | unknown: 1390136216) (gdb) bt #0 mozilla::pkix::CheckKeyUsage (endEntityOrCA=(mozilla::pkix::MustBeCA | unknown: 1390136216), encodedKeyUsage=0x7fffb3004aa0, requiredKeyUsageIfPresent=requiredKeyUsageIfPresent@entry=mozilla::pkix::digitalSignature) at /build/buildd/firefox-31.0+build1/security/pkix/lib/pkixcheck.cpp:55 #1 0x00007ffff1cc19ed in mozilla::pkix::CheckIssuerIndependentProperties (trustDomain=..., cert=..., time=time@entry=1406341186571161, endEntityOrCA=endEntityOrCA@entry=mozilla::pkix::MustBeEndEntity, requiredKeyUsageIfPresent=<optimized out>, requiredEKUIfPresent=requiredEKUIfPresent@entry=SEC_OID_EXT_KEY_USAGE_SERVER_AUTH, requiredPolicy=requiredPolicy@entry=SEC_OID_X509_ANY_POLICY, subCACount=subCACount@entry=0, trustLevelOut=trustLevelOut@entry=0x7fffc02fa54c) at /build/buildd/firefox-31.0+build1/security/pkix/lib/pkixcheck.cpp:635 #2 0x00007ffff1cc0bf9 in mozilla::pkix::BuildForward (trustDomain=..., subject=..., time=time@entry=1406341186571161, endEntityOrCA=endEntityOrCA@entry=mozilla::pkix::MustBeEndEntity, requiredKeyUsageIfPresent=requiredKeyUsageIfPresent@entry=mozilla::pkix::digitalSignature, requiredEKUIfPresent=requiredEKUIfPresent@entry=SEC_OID_EXT_KEY_USAGE_SERVER_AUTH, requiredPolicy=requiredPolicy@entry=SEC_OID_X509_ANY_POLICY, stapledOCSPResponse=stapledOCSPResponse@entry=0x0, subCACount=subCACount@entry=0, results=...) at /build/buildd/firefox-31.0+build1/security/pkix/lib/pkixbuild.cpp:216 #3 0x00007ffff1cc1093 in mozilla::pkix::BuildCertChain (trustDomain=..., certToDup=certToDup@entry=0x7fffb2509020, time=time@entry=1406341186571161, endEntityOrCA=endEntityOrCA@entry=mozilla::pkix::MustBeEndEntity, requiredKeyUsageIfPresent=requiredKeyUsageIfPresent@entry=mozilla::pkix::digitalSignature, requiredEKUIfPresent=requiredEKUIfPresent@entry=SEC_OID_EXT_KEY_USAGE_SERVER_AUTH, requiredPolicy=requiredPolicy@entry=SEC_OID_X509_ANY_POLICY, stapledOCSPResponse=stapledOCSPResponse@entry=0x0, results=...) at /build/buildd/firefox-31.0+build1/security/pkix/lib/pkixbuild.cpp:343 #4 0x00007ffff1cbe1b6 in mozilla::psm::BuildCertChainForOneKeyUsage (trustDomain=..., cert=cert@entry=0x7fffb2509020, time=time@entry=1406341186571161, requiredPolicy=requiredPolicy@entry=SEC_OID_X509_ANY_POLICY, stapledOCSPResponse=stapledOCSPResponse@entry=0x0, builtChain=..., eku=SEC_OID_EXT_KEY_USAGE_SERVER_AUTH, ku3=mozilla::pkix::keyAgreement, ku2=mozilla::pkix::keyEncipherment, ku1=mozilla::pkix::digitalSignature) at /build/buildd/firefox-31.0+build1/security/certverifier/CertVerifier.cpp:206 #5 0x00007ffff1cbe510 in mozilla::psm::CertVerifier::MozillaPKIXVerifyCert (this=this@entry=0x7fffc2e35800, cert=cert@entry=0x7fffb2509020, usage=usage@entry=2, time=time@entry=1406341186571161, pinArg=pinArg@entry=0x7fffb00db160, flags=flags@entry=0, stapledOCSPResponse=0x0, validationChain=validationChain@entry=0x7fffc02fab58, evOidPolicy=evOidPolicy@entry=0x7fffc02fabdc) at /build/buildd/firefox-31.0+build1/security/certverifier/CertVerifier.cpp:331 #6 0x00007ffff1cbe8ad in mozilla::psm::CertVerifier::VerifyCert (this=this@entry=0x7fffc2e35800, cert=cert@entry=0x7fffb2509020, stapledOCSPResponse=<optimized out>, usage=usage@entry=2, time=time@entry=1406341186571161, pinArg=0x7fffb00db160, flags=flags@entry=0, validationChain=validationChain@entry=0x7fffc02fab58, evOidPolicy=evOidPolicy@entry=0x7fffc02fabdc, verifyLog=verifyLog@entry=0x0) at /build/buildd/firefox-31.0+build1/security/certverifier/CertVerifier.cpp:458 #7 0x00007ffff1cbf11c in mozilla::psm::CertVerifier::VerifySSLServerCert (this=this@entry=0x7fffc2e35800, peerCert=peerCert@entry=0x7fffb2509020, stapledOCSPResponse=stapledOCSPResponse@entry=0x0, time=time@entry=1406341186571161, pinarg=pinarg@entry=0x7fffb00db160, hostname=0x7fffb0f5ec80 "dbadmin.quietfountain.com", saveIntermediatesInPermanentDatabase=true, certChainOut=certChainOut@entry=0x0, evOidPolicy=evOidPolicy@entry=0x7fffc02fabdc) at /build/buildd/firefox-31.0+build1/security/certverifier/CertVerifier.cpp:831 #8 0x00007ffff2dc5326 in mozilla::psm::(anonymous namespace)::AuthCertificate (certVerifier=..., infoObject=0x7fffb00db160, cert=0x7fffb2509020, stapledOCSPResponse=0x0, providerFlags=<optimized out>, time=1406341186571161) at /build/buildd/firefox-31.0+build1/security/manager/ssl/src/SSLServerCertVerification.cpp:972 #9 0x00007ffff2dc54ec in mozilla::psm::(anonymous namespace)::SSLServerCertVerificationJob::Run (this=0x7fffb3ebd740) at /build/buildd/firefox-31.0+build1/security/manager/ssl/src/SSLServerCertVerification.cpp:1115 #10 0x00007ffff1d0efd1 in nsThreadPool::Run (this=0x7ffff6c24f00) at /build/buildd/firefox-31.0+build1/xpcom/threads/nsThreadPool.cpp:211 #11 0x00007ffff1d0ce99 in nsThread::ProcessNextEvent (this=0x7fffbaff9a00, mayWait=<optimized out>, result=0x7fffc02faddf) at /build/buildd/firefox-31.0+build1/xpcom/threads/nsThread.cpp:715 #12 0x00007ffff1ccb4fd in NS_ProcessNextEvent (thread=<optimized out>, mayWait=mayWait@entry=true) at /build/buildd/firefox-31.0+build1/xpcom/glue/nsThreadUtils.cpp:263 #13 0x00007ffff1eaf52d in mozilla::ipc::MessagePumpForNonMainThreads::Run (this=0x7fffb0f80c40, aDelegate=0x7fffbb1f86e0) at /build/buildd/firefox-31.0+build1/ipc/glue/MessagePump.cpp:336 #14 0x00007ffff1ea0f21 in RunHandler (this=0x7fffbb1f86e0) at /build/buildd/firefox-31.0+build1/ipc/chromium/src/base/message_loop.cc:222 #15 MessageLoop::Run (this=this@entry=0x7fffbb1f86e0) at /build/buildd/firefox-31.0+build1/ipc/chromium/src/base/message_loop.cc:196 #16 0x00007ffff1d0d86d in nsThread::ThreadFunc (arg=0x7fffbaff9a00) at /build/buildd/firefox-31.0+build1/xpcom/threads/nsThread.cpp:316 #17 0x00007ffff69e9488 in _pt_root (arg=0x7fffb00daf20) at /build/buildd/firefox-31.0+build1/./nsprpub/pr/src/pthreads/ptthread.c:212 #18 0x00007ffff73b6182 in start_thread (arg=0x7fffc02fb700) at pthread_create.c:312 #19 0x00007ffff70e330d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 (gdb) frame 1 #1 0x00007ffff1cc19ed in mozilla::pkix::CheckIssuerIndependentProperties (trustDomain=..., cert=..., time=time@entry=1406341186571161, endEntityOrCA=endEntityOrCA@entry=mozilla::pkix::MustBeEndEntity, requiredKeyUsageIfPresent=<optimized out>, requiredEKUIfPresent=requiredEKUIfPresent@entry=SEC_OID_EXT_KEY_USAGE_SERVER_AUTH, requiredPolicy=requiredPolicy@entry=SEC_OID_X509_ANY_POLICY, subCACount=subCACount@entry=0, trustLevelOut=trustLevelOut@entry=0x7fffc02fa54c) at /build/buildd/firefox-31.0+build1/security/pkix/lib/pkixcheck.cpp:635 635 requiredKeyUsageIfPresent); (gdb) p endEntityOrCA $102 = mozilla::pkix::MustBeEndEntity (gdb) frame 0 #0 mozilla::pkix::CheckKeyUsage (endEntityOrCA=(mozilla::pkix::MustBeCA | unknown: 1390136216), encodedKeyUsage=0x7fffb3004aa0, requiredKeyUsageIfPresent=requiredKeyUsageIfPresent@entry=mozilla::pkix::digitalSignature) at /build/buildd/firefox-31.0+build1/security/pkix/lib/pkixcheck.cpp:55 55 if (!encodedKeyUsage) { (gdb) p endEntityOrCA $103 = (mozilla::pkix::MustBeCA | unknown: 1390136216) (gdb) quit Expected results: The variable endEntityOrCA passed should be the same when the CheckKeyUsage function begins. as it was in the calling function. The result of the high value for the enum that should be 0 or 1 is the routine called with checks hoping for an end entity are instead checked as if a CA, and of course the checks fail.
Updated•10 years ago
|
QA Whiteboard: [bugday-20140728]
Component: Untriaged → Security
Updated•10 years ago
|
Version: 30 Branch → 31 Branch
Reporter | ||
Comment 1•10 years ago
|
||
This happens on default Ubuntu LTS Trusty version of Firefox.
Updated•10 years ago
|
Component: Security → Security: PSM
Product: Firefox → Core
Reporter | ||
Comment 2•10 years ago
|
||
The https:// that fails above, works with Chromium browser after importing the internal CA. These are all the default systems on ubuntu trusty LTS. "v31 Mozillia Firefox for Ubuntu Canonical 1.0" Possibly of interest, the internal CA has a 3072 bit dsa key. openssl dsaparam -out foo-ca.dsaparam -genkey 3072 openssl gendsa -out foo-ca.key foo-ca.dsaparam
Reporter | ||
Comment 3•10 years ago
|
||
mistake |
Is the compiler just emitting bad code? Look at this around line 141. It appears there is a test but no following jump. 136 if (endEntityOrCA != EndEntityOrCA::MustBeCA) { 0x00007ffff1cbf3ef <+291>: dec %r13d 0x00007ffff1cbf3f2 <+294>: je 0x7ffff1cbf3ff <mozilla::pkix::CheckKeyUsage(SECItemStr const*, mozilla::pkix::KeyUsage, mozilla::pkix::EndEntityOrCA)+307> 137 // RFC 5280 says "The keyCertSign bit is asserted when the subject public 138 // key is used for verifying signatures on public key certificates. If the 139 // keyCertSign bit is asserted, then the cA bit in the basic constraints 140 // extension (Section 4.2.1.9) MUST also be asserted." 141 if ((bits & KeyUsageToBitMask(KeyUsage::keyCertSign)) != 0) { 0x00007ffff1cbf3f4 <+296>: testb $0x4,0xe(%rsp) 142 return Fail(RecoverableError, SEC_ERROR_INADEQUATE_KEY_USAGE); 143 } 144 } 145 146 // The padding applies to the last byte, so skip to the last byte. 147 while (!value.AtEnd()) { 0x00007ffff1cbf3ff <+307>: mov 0x28(%rsp),%rax 0x00007ffff1cbf404 <+312>: cmp %rax,0x20(%rsp) 0x00007ffff1cbf409 <+317>: je 0x7ffff1cbf41a <mozilla::pkix::CheckKeyUsage(SECItemStr const*, mozilla::pkix::KeyUsage, mozilla::pkix::EndEntityOrCA)+334> 148 if (value.Read(bits) != der::Success) {
Reporter | ||
Comment 5•10 years ago
|
||
Moving all the local variables to the top of the function and moving the enum value to the last argument from the first cures the corruption in the last argument, but the website still fails to load with the same error. I'm noticing during the debug process worker threads appear to end while this function is running. My hunch is that other threads free memory being actively used by this function and it's just a matter of chance if the memory is re-used before this function ends, corrupting the results. Result CheckKeyUsage(const SECItem* encodedKeyUsage, KeyUsage requiredKeyUsageIfPresent, EndEntityOrCA endEntityOrCA) { uint8_t numberOfPaddingBits; uint8_t bits; der::Input input; der::Input value; uint8_t paddingMask; if (!encodedKeyUsage) {
Reporter | ||
Comment 6•10 years ago
|
||
I'm not a firefox developer, so it's up to people who actually know this code to take it from here. For what it's worth: today's install of 31.0+build1-0ubuntu0.14.04.1 loaded the same website without problems. No changes to the CA or website cert.
Comment 7•10 years ago
|
||
See bug 1044350. It could very well be the case that this is/was due to a compiler bug. It does seem to be the case that GCC has had multiple bugs with compiling enum class. I'm not sure even if the workaround for bug 1044350 will completely fix it, or if an even newer version of GCC is required. It could also be the case that our code is doing some undefined behavior. The most likely cause of undefined behavior is casting a value to the enum class type, where the value is outside the range of the enum. But, exactly to avoid that class of error, we (I) always cast the other way, from the enum to the integer type. So, I think it is more likely a compiler bug. But, pay attention for questionable casts, because I could well be wrong.
See Also: → 1077887
Comment 9•9 years ago
|
||
Hi, Just wanted to give a friendly ping concerning comment 7 and the ni? request in comment 8. Thanks!
Reporter | ||
Comment 10•9 years ago
|
||
I think this bug surfaced owing to the effort to block access to previously favored, now disfavored certs, without the possibility of override. Seems to me if it's possible to override security warnings and yet visit sites in the case of invalid certs or unsigned certs, what purpose is served by making it impossible to override in the case of otherwise valid certs with disfavored characteristics? Seems Big-Brother-ish, not allowing users to proceed after notice. In the affected cases, I've moved to chrome which allows the affected to proceed. Strange world when open source is more restrictive than private source software.
Flags: needinfo?(hcoin)
Status: UNCONFIRMED → RESOLVED
Closed: 8 years ago
Resolution: --- → WORKSFORME
You need to log in
before you can comment on or make changes to this bug.
Description
•