Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto/x509: unable to parse certificate with a negative serial number #8265

Closed
gopherbot opened this issue Jun 23, 2014 · 30 comments
Closed
Milestone

Comments

@gopherbot
Copy link

by ayazdi:

go version: go1.2.1 linux/amd64

Trying to parse an X509 certificate with a negative serial number results in the
following error:

x509: negative serial number

(see http://play.golang.org/p/zpXKadV5mo for an example)

This means an SSL/TLS connection cannot be established to a server that uses this kind
of certificate.

Although RFC 5280 [1] section 4.1.2.2 specifies that serial numbers MUST be positive, it
also says that implementations SHOULD handle non-positive serial numbers gracefully. 

Note that RFC 2459 (obsoleted by RFC 3280, which was in turn obsoleted by 5280) did not
require the SN to be positive.

[1] http://www.ietf.org/rfc/rfc5280.txt
@gopherbot
Copy link
Author

Comment 1 by mcmoranbjr:

Aside from not following the RFC, the behavior is inconsistent within std library
consumers of tls which make use of tls.Client connections. 
Check out the following for more detail:
https://groups.google.com/forum/#!topic/golang-nuts/lEfVw4ySj5g

@griesemer
Copy link
Contributor

Comment 2:

Labels changed: added release-go1.4maybe, repo-main.

@rsc
Copy link
Contributor

rsc commented Oct 3, 2014

Comment 3:

->agl for triage

Status changed to Accepted.

@agl
Copy link
Contributor

agl commented Oct 3, 2014

Comment 4:

If you find a CA that is issuing certificates like this, please let me know and I'll
complain to them.

Owner changed to @agl.

@rsc
Copy link
Contributor

rsc commented Oct 6, 2014

Comment 5:

Sounds like a 'WorkingAsIntended' to me.

Status changed to WorkingAsIntended.

@bytheway
Copy link

bytheway commented Oct 8, 2014

Comment 6:

I am a new user to Go and just experienced this today.  We use the WebLogic java
application server and by default, it generates certificates for admin ports that use
negative serial numbers.
Yes, we probably should get "real" certs, but all the servers are behind a firewall, for
internal use only, so we've never bothered.
What about eliminating the negative serial number check only when InsecureSkipVerify ==
true?

@gopherbot
Copy link
Author

Comment 7 by lgtdrivesme:

The negative serial was coming from HP iLO3 devices running firmware 1.5. The device
certificate was reissued during the firmware update and because, HP, the new certificate
had a negative serial number. Subsequent firmware updates fixed the issue. I would
support the notion this is a vendor problem and the suggestion the vendor be set ablaze
or clubbed to death.

@gopherbot
Copy link
Author

Comment 8 by mcmoranbjr:

The negative serial was coming from HP iLO3 devices running firmware 1.5. The device
certificate was reissued during the firmware update and because, HP, the new certificate
had a negative serial number. Subsequent firmware updates fixed the issue. I would
support the notion this is a vendor problem and the suggestion the vendor be set ablaze
or clubbed to death.

@bytheway
Copy link

bytheway commented Oct 8, 2014

Comment 9:

I agree that this is a bad practice by vendors, but not having some kind of override
makes using go

@bytheway
Copy link

bytheway commented Oct 8, 2014

Comment 10:

I agree that this is a bad vendor practice, and in a perfect world we could just make
every vendor do the right thing.
But, by making this a hard requirement, with no way to turn it off, it makes it hard for
us to replace some of our current (ruby) scripts with equivalent/better go versions.

@gopherbot
Copy link
Author

Comment 11 by takekazu.omi@kyrt.in:

> I am a new user to Go and just experienced this today
me too!
I used Windows 8.1 makecert for create self signed certificates.
$ makecert -r -pe -n "CN=Hoge 20141026001" -a sha1 -ss My -len 2048 -sy 24 -b 10/26/2014
-e 01/01/2024 -sv hoge20141026001.pvk hoge20141026001.cer
I got negative serial number 2 times out of 4.
$ openssl x509 -in .\takekazu_omi_azure_20141026005.cer -inform der -serial
serial=-05B57C18EAC6AB57BC5135E6105B880B

@gopherbot
Copy link
Author

Comment 12 by mendsley:

Just hit this today. We were issued a certificate with a negative serial from 
Microsoft's Xbox Cloud Security CA.

@marconfus
Copy link

So you intentionally break a lot of setups because you don't want to implement the "SHOULD handle non-positive serial numbers gracefully" which every popular browser does?
Really?

@bytheway
Copy link

Is there any chance that this issue can be revisited? Is there an approach to fixing this on the client side that would be acceptable to the Golang Devs?

I would really want to use go for an internal URL checker/monitor, but this behavior is blocking an easy implementation.

@ioanvapi
Copy link

"http://www.ietf.org/rfc/rfc5280.txt
4.1.2.2. Serial Number
The serial number MUST be a positive integer assigned by the CA to each certificate.....
Note: Non-conforming CAs may issue certificates with serial numbers that are negative or zero. Certificate users SHOULD be prepared to gracefully handle such certificates."
I really need this feature to be implemented. Thanks.

@bradfitz
Copy link
Contributor

Please paste or link such certificates here for @agl to look at.

@agl
Copy link
Contributor

agl commented Jul 4, 2015

I don't believe that negative serial numbers are reasonable. Software that's producing them is displaying a pretty shocking level of quality control: it suggests that the developers are not even checking a handful of the generated certificates.

None the less, sometimes reality does demand compromises. Someone claimed above that Windows 8's makecert is generating these broken certificates. If people can confirm that this bug is that widespread then that would start to justify giving up.

@benjamin-thomas
Copy link

Please, see this thread for reference: https://groups.google.com/forum/#!topic/golang-nuts/Jxbc0Aazzcw

Could you at least provide a workaround? I ran into this issue myself trying to communicate with HP LaserJet printers (not all of them have negative serial numbers), over a LAN.

Those printers present self signed certificates out of the factory, and thus fall into the category "Non-conforming CAs" I guess.

One can use a regular web browser to connect to the printer's web interface without any problems (once you override the security warnings)

Security is secondary in my scenario.

Some devices won't allow HTTP connections, or may redirect to HTTPS on certain pages. I still need to access those pages programmatically.

My simplified code looks like this.

client := &http.Client{
    Transport: &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    },
}

resp, err := client.Get(url)
if err != nil {
    return fmt.Errorf("Failed getting '%s': %s ", url, err)
}

I feel the library could be less strict, considering InsecureSkipVerify is set to true, and that in practice other programs in the wild do not abort on such an anomaly.

The only solution so far is to recompile go after having edited it's source which is just messy/clunky.

Thanks for your feedback.

@aggieben
Copy link

I also have this problem while trying to use Fiddler to proxy a golang program's http connections.

@agl
Copy link
Contributor

agl commented Jul 17, 2015

aggieben: the Fiddler author reports that that was a bug fixed last year: https://twitter.com/ericlaw/status/622168757419413504

@ericlaw1979
Copy link

In 2014, I fixed a bug in Fiddler's CertMaker addon (BouncyCastle-based certificate generator) related to serial number values; however this isn't the default generator in Fiddler. The default generator, at the moment, is MakeCert.exe, so if that utility is generating negative serial numbers (and it appears to, even on Windows 10) you could still encounter this issue. One clarification though: Makecert isn't a part of Windows itself; it calls the CAPI apis. I believe it was last publicly shipped as a VS2008 redistributable, although some programs like Fiddler still bundle it.

Current versions of Fiddler allow you to either use the CertMaker add-on (http://www.fiddler2.com/r/?fiddlercertmaker), or use the Win7+ CertEnroll interfaces (click Tools > Fiddler Options > HTTPS and click the blue hyperlink "Default certificate maker" and select CertEnroll). The former definitely won't give you a negative serial number and the latter shouldn't (CertEnroll is generally higher quality than makecert.exe).

Now, having said all that, makecert-generated certs seem to be pretty widespread; the Mozilla guys backed out one of their recent changes to accommodate another quirk of such certificates (see https://bugzilla.mozilla.org/show_bug.cgi?id=1042479)

On a quick test Win10, makecert.exe generated a certificate with the following serial number:

a633fb4f da68a188 42816c76 b2482cc4

@benjamin-thomas
Copy link

By coincidence (google search), I found a printer on the internet, returning such a certificate.

So you may have a look at it.

echo '' | openssl s_client -connect 128.175.122.84:443 -prexit 2>/dev/null | sed -n -e '/BEGIN\ CERTIFICATE/,/END\ CERTIFICATE/ p' >/tmp/cert; openssl x509 -in /tmp/cert -serial | head -1
# output: serial=-4508439A

Let's say, for whatever reason, I would need to interact with this printer. Then I'm stuck.

It seems a lot of people are affected by this. Please provide an alternative to bypass this restriction. For example you could require an env var to be set.

As you can see, one can connect with a browser once the security warnings have been acknowledged.

@gwatts
Copy link

gwatts commented Sep 27, 2015

I wrote a little tool to extract CA certificates from Mozilla's NSS project (which is also used by Debian, Ubuntu, curl, etc) and that set includes a CA certificate with a negative serial number which my tool has no choice but to drop.

That certificate is labeled as "EC-ACC" in their source ( http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt )

Some discussion around the validity of that serial number occurred at time of its inclusion:
https://bugzilla.mozilla.org/show_bug.cgi?id=707995
https://groups.google.com/forum/#!topic/mozilla.dev.security.policy/pOUJJFJdP_4

While one can argue that a negative serial number is incorrect, it's pretty unfortunate that Go cannot be liberal in accepting it, given the fact that such serial numbers are in use in practice. If the net/http package was quite as strict about what it would accept, we'd probably not have useful web services built in Go ;-)

Here's the cert for reference:

-----BEGIN CERTIFICATE-----
MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE
BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w
ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD
VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE
CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT
BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7
MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt
SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl
Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh
cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK
w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT
ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4
HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a
E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw
0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD
VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0
Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l
dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ
lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa
Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe
l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2
E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D
5EI=
-----END CERTIFICATE-----

@duesee
Copy link

duesee commented Nov 18, 2015

As far as I understand this is not a technical problem, but rather a conflict of opinions?

So here is our experience with this "issue"...

We are working on a large set of x509 certificates and found approximately 100000 certificates with a negative serial number -- all of them which can't be processed due to this issue.

Quoting RFC5280, again: "Certificate users SHOULD be prepared to gracefully handle (...) certificates (with a negative serial number)"

So, when we become prepared?

Just for reference: I posted the same comment here.

@ruzickap
Copy link

Hello I have the same problem as @duesee. I'l also getting the "negative serial number" when using the "govc"/"govmomi" vmware access.

@nmische
Copy link

nmische commented Nov 27, 2015

I'm hitting the x509: negative serial number issue as well. Unfortunately I have no control over the certificate used on the service I'm attempting to reach.

@gopherbot
Copy link
Author

CL https://golang.org/cl/17247 mentions this issue.

@mikioh mikioh modified the milestones: Go1.6, Go1.4 Nov 27, 2015
agl added a commit that referenced this issue Nov 28, 2015
Some software that produces certificates doesn't encode integers
correctly and, about half the time, ends up producing certificates with
serial numbers that are actually negative.

This buggy software, sadly, appears to be common enough that we should
let these errors pass. This change allows a Certificate.SerialNumber to
be negative.

Fixes #8265.

Change-Id: Ief35dae23988fb6d5e2873e3c521366fb03c6af4
Reviewed-on: https://go-review.googlesource.com/17247
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
@jcajka
Copy link
Contributor

jcajka commented Dec 10, 2015

Would it be possible to cherry-pick fix for this issue in to the 1.5(1.4) next minor release?

@bradfitz
Copy link
Contributor

This isn't the type of change we cherry-pick to point releases. It's not a critical security issue nor a crash in the runtime.

@jcajka
Copy link
Contributor

jcajka commented Dec 10, 2015

@bradfitz I thought that it have chance to be included as it seems as long wished for fix(/workaround).

Thanks for quick response and clarification.

This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests