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

x/crypto/ocsp: response should not contain param element for hashingAlgorithm #69078

Open
sdash713 opened this issue Aug 27, 2024 · 6 comments
Open
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@sdash713
Copy link

Go version

go 1.23

Output of go env in your module/workspace:

NA

What did you do?

The code is present here https://go.dev/play/p/OKCJFUwCu83
I am trying to generate OCSP response. The generated OCSP response is not as per the RFC recommendations.

package main

import (
	"crypto/x509"
	"encoding/hex"
	"fmt"
	"time"

	"golang.org/x/crypto/ocsp"
)

func DumpOCSPResponse() {
	leafCert, _ := hex.DecodeString(leafCertHex)
	leaf, err := x509.ParseCertificate(leafCert)

	issuerCert, _ := hex.DecodeString(issuerCertHex)
	issuer, err := x509.ParseCertificate(issuerCert)

	responderCert, _ := hex.DecodeString(responderCertHex)
	responder, err := x509.ParseCertificate(responderCert)

	responderPrivateKeyDER, _ := hex.DecodeString(responderPrivateKeyHex)
	responderPrivateKey, err := x509.ParsePKCS1PrivateKey(responderPrivateKeyDER)

	// producedAt := time.Now().Truncate(time.Minute)
	thisUpdate := time.Date(2010, 7, 7, 15, 1, 5, 0, time.UTC)
	nextUpdate := time.Date(2010, 7, 7, 18, 35, 17, 0, time.UTC)
	template := ocsp.Response{
		Status:       ocsp.Good,
		SerialNumber: leaf.SerialNumber,
		ThisUpdate:   thisUpdate,
		NextUpdate:   nextUpdate,
		Certificate:  responder,
	}

	responseBytes, err := ocsp.CreateResponse(issuer, responder, template, responderPrivateKey)

	if err != nil {
		print("Failed")
	}
	resp, err := ocsp.ParseResponse(responseBytes, nil)

	if err != nil {
		print("Failed")
	}
	fmt.Println(hex.Dump(resp.TBSResponseData))

}

func main() {
	DumpOCSPResponse()
}

const leafCertHex = "308203c830820331a0030201020210017f77deb3bcbb235d44ccc7dba62e72300d06092a" +
	"864886f70d01010505003081ba311f301d060355040a1316566572695369676e20547275" +
	"7374204e6574776f726b31173015060355040b130e566572695369676e2c20496e632e31" +
	"333031060355040b132a566572695369676e20496e7465726e6174696f6e616c20536572" +
	"766572204341202d20436c617373203331493047060355040b13407777772e7665726973" +
	"69676e2e636f6d2f43505320496e636f72702e6279205265662e204c494142494c495459" +
	"204c54442e286329393720566572695369676e301e170d3132303632313030303030305a" +
	"170d3133313233313233353935395a3068310b3009060355040613025553311330110603" +
	"550408130a43616c69666f726e6961311230100603550407130950616c6f20416c746f31" +
	"173015060355040a130e46616365626f6f6b2c20496e632e311730150603550403140e2a" +
	"2e66616365626f6f6b2e636f6d30819f300d06092a864886f70d010101050003818d0030" +
	"818902818100ae94b171e2deccc1693e051063240102e0689ae83c39b6b3e74b97d48d7b" +
	"23689100b0b496ee62f0e6d356bcf4aa0f50643402f5d1766aa972835a7564723f39bbef" +
	"5290ded9bcdbf9d3d55dfad23aa03dc604c54d29cf1d4b3bdbd1a809cfae47b44c7eae17" +
	"c5109bee24a9cf4a8d911bb0fd0415ae4c3f430aa12a557e2ae10203010001a382011e30" +
	"82011a30090603551d130402300030440603551d20043d303b3039060b6086480186f845" +
	"01071703302a302806082b06010505070201161c68747470733a2f2f7777772e76657269" +
	"7369676e2e636f6d2f727061303c0603551d1f043530333031a02fa02d862b687474703a" +
	"2f2f535652496e746c2d63726c2e766572697369676e2e636f6d2f535652496e746c2e63" +
	"726c301d0603551d250416301406082b0601050507030106082b06010505070302300b06" +
	"03551d0f0404030205a0303406082b0601050507010104283026302406082b0601050507" +
	"30018618687474703a2f2f6f6373702e766572697369676e2e636f6d30270603551d1104" +
	"20301e820e2a2e66616365626f6f6b2e636f6d820c66616365626f6f6b2e636f6d300d06" +
	"092a864886f70d0101050500038181005b6c2b75f8ed30aa51aad36aba595e555141951f" +
	"81a53b447910ac1f76ff78fc2781616b58f3122afc1c87010425e9ed43df1a7ba6498060" +
	"67e2688af03db58c7df4ee03309a6afc247ccb134dc33e54c6bc1d5133a532a73273b1d7" +
	"9cadc08e7e1a83116d34523340b0305427a21742827c98916698ee7eaf8c3bdd71700817"

const issuerCertHex = "30820383308202eca003020102021046fcebbab4d02f0f926098233f93078f300d06092a" +
	"864886f70d0101050500305f310b300906035504061302555331173015060355040a130e" +
	"566572695369676e2c20496e632e31373035060355040b132e436c617373203320507562" +
	"6c6963205072696d6172792043657274696669636174696f6e20417574686f7269747930" +
	"1e170d3937303431373030303030305a170d3136313032343233353935395a3081ba311f" +
	"301d060355040a1316566572695369676e205472757374204e6574776f726b3117301506" +
	"0355040b130e566572695369676e2c20496e632e31333031060355040b132a5665726953" +
	"69676e20496e7465726e6174696f6e616c20536572766572204341202d20436c61737320" +
	"3331493047060355040b13407777772e766572697369676e2e636f6d2f43505320496e63" +
	"6f72702e6279205265662e204c494142494c495459204c54442e28632939372056657269" +
	"5369676e30819f300d06092a864886f70d010101050003818d0030818902818100d88280" +
	"e8d619027d1f85183925a2652be1bfd405d3bce6363baaf04c6c5bb6e7aa3c734555b2f1" +
	"bdea9742ed9a340a15d4a95cf54025ddd907c132b2756cc4cabba3fe56277143aa63f530" +
	"3e9328e5faf1093bf3b74d4e39f75c495ab8c11dd3b28afe70309542cbfe2b518b5a3c3a" +
	"f9224f90b202a7539c4f34e7ab04b27b6f0203010001a381e33081e0300f0603551d1304" +
	"0830060101ff02010030440603551d20043d303b3039060b6086480186f8450107010130" +
	"2a302806082b06010505070201161c68747470733a2f2f7777772e766572697369676e2e" +
	"636f6d2f43505330340603551d25042d302b06082b0601050507030106082b0601050507" +
	"030206096086480186f8420401060a6086480186f845010801300b0603551d0f04040302" +
	"0106301106096086480186f842010104040302010630310603551d1f042a30283026a024" +
	"a0228620687474703a2f2f63726c2e766572697369676e2e636f6d2f706361332e63726c" +
	"300d06092a864886f70d010105050003818100408e4997968a73dd8e4def3e61b7caa062" +
	"adf40e0abb753de26ed82cc7bff4b98c369bcaa2d09c724639f6a682036511c4bcbf2da6" +
	"f5d93b0ab598fab378b91ef22b4c62d5fdb27a1ddf33fd73f9a5d82d8c2aead1fcb028b6" +
	"e94948134b838a1b487b24f738de6f4154b8ab576b06dfc7a2d4a9f6f136628088f28b75" +
	"d68071"

const responderPrivateKeyHex = "308204a40201000282010100e8155f2d3e6f2e8d14c62a788bd462f9f844e7a6977c83ef" +
	"1099f0f6616ec5265b56f356e62c5400f0b06a2e7945a82752c636df32a895152d6074df" +
	"1701dc6ccfbcbec75a70bd2b55ae2be7e6cad3b5fd4cd5b7790ab401a436d3f5f346074f" +
	"fde8a99d5b723350f0a112076614b12ef79c78991b119453445acf2416ab0046b540db14" +
	"c9fc0f27b8989ad0f63aa4b8aefc91aa8a72160c36307c60fec78a93d3fddf4259902aa7" +
	"7e7332971c7d285b6a04f648993c6922a3e9da9adf5f81508c3228791843e5d49f24db2f" +
	"1290bafd97e655b1049a199f652cd603c4fafa330c390b0da78fbbc67e8fa021cbd74eb9" +
	"6222b12ace31a77dcf920334dc94581b02030100010282010100bcf0b93d7238bda329a8" +
	"72e7149f61bcb37c154330ccb3f42a85c9002c2e2bdea039d77d8581cd19bed94078794e" +
	"56293d601547fc4bf6a2f9002fe5772b92b21b254403b403585e3130cc99ccf08f0ef81a" +
	"575b38f597ba4660448b54f44bfbb97072b5a2bf043bfeca828cf7741d13698e3f38162b" +
	"679faa646b82abd9a72c5c7d722c5fc577a76d2c2daac588accad18516d1bbad10b0dfa2" +
	"05cfe246b59e28608a43942e1b71b0c80498075121de5b900d727c31c42c78cf1db5c0aa" +
	"5b491e10ea4ed5c0962aaf2ae025dd81fa4ce490d9d6b4a4465411d8e542fc88617e5695" +
	"1aa4fc8ea166f2b4d0eb89ef17f2b206bd5f1014bf8fe0e71fe62f2cccf102818100f2dc" +
	"ddf878d553286daad68bac4070a82ffec3dc4666a2750f47879eec913f91836f1d976b60" +
	"daf9356e078446dafab5bd2e489e5d64f8572ba24a4ba4f3729b5e106c4dd831cc2497a7" +
	"e6c7507df05cb64aeb1bbc81c1e340d58b5964cf39cff84ea30c29ec5d3f005ee1362698" +
	"07395037955955655292c3e85f6187fa1f9502818100f4a33c102630840705f8c778a47b" +
	"87e8da31e68809af981ac5e5999cf1551685d761cdf0d6520361b99aebd5777a940fa64d" +
	"327c09fa63746fbb3247ec73a86edf115f1fe5c83598db803881ade71c33c6e956118345" +
	"497b98b5e07bb5be75971465ec78f2f9467e1b74956ca9d4c7c3e314e742a72d8b33889c" +
	"6c093a466cef0281801d3df0d02124766dd0be98349b19eb36a508c4e679e793ba0a8bef" +
	"4d786888c1e9947078b1ea28938716677b4ad8c5052af12eb73ac194915264a913709a0b" +
	"7b9f98d4a18edd781a13d49899f91c20dbd8eb2e61d991ba19b5cdc08893f5cb9d39e5a6" +
	"0629ea16d426244673b1b3ee72bd30e41fac8395acac40077403de5efd028180050731dd" +
	"d71b1a2b96c8d538ba90bb6b62c8b1c74c03aae9a9f59d21a7a82b0d572ef06fa9c807bf" +
	"c373d6b30d809c7871df96510c577421d9860c7383fda0919ece19996b3ca13562159193" +
	"c0c246471e287f975e8e57034e5136aaf44254e2650def3d51292474c515b1588969112e" +
	"0a85cc77073e9d64d2c2fc497844284b02818100d71d63eabf416cf677401ebf965f8314" +
	"120b568a57dd3bd9116c629c40dc0c6948bab3a13cc544c31c7da40e76132ef5dd3f7534" +
	"45a635930c74326ae3df0edd1bfb1523e3aa259873ac7cf1ac31151ec8f37b528c275622" +
	"48f99b8bed59fd4da2576aa6ee20d93a684900bf907e80c66d6e2261ae15e55284b4ed9d" +
	"6bdaa059"

const responderCertHex = "308202e2308201caa003020102020101300d06092a864886f70d01010b05003019311730" +
	"150603550403130e4f43535020526573706f6e646572301e170d31353031333031353530" +
	"33335a170d3136303133303135353033335a3019311730150603550403130e4f43535020" +
	"526573706f6e64657230820122300d06092a864886f70d01010105000382010f00308201" +
	"0a0282010100e8155f2d3e6f2e8d14c62a788bd462f9f844e7a6977c83ef1099f0f6616e" +
	"c5265b56f356e62c5400f0b06a2e7945a82752c636df32a895152d6074df1701dc6ccfbc" +
	"bec75a70bd2b55ae2be7e6cad3b5fd4cd5b7790ab401a436d3f5f346074ffde8a99d5b72" +
	"3350f0a112076614b12ef79c78991b119453445acf2416ab0046b540db14c9fc0f27b898" +
	"9ad0f63aa4b8aefc91aa8a72160c36307c60fec78a93d3fddf4259902aa77e7332971c7d" +
	"285b6a04f648993c6922a3e9da9adf5f81508c3228791843e5d49f24db2f1290bafd97e6" +
	"55b1049a199f652cd603c4fafa330c390b0da78fbbc67e8fa021cbd74eb96222b12ace31" +
	"a77dcf920334dc94581b0203010001a3353033300e0603551d0f0101ff04040302078030" +
	"130603551d25040c300a06082b06010505070309300c0603551d130101ff04023000300d" +
	"06092a864886f70d01010b05000382010100718012761b5063e18f0dc44644d8e6ab8612" +
	"31c15fd5357805425d82aec1de85bf6d3e30fce205e3e3b8b795bbe52e40a439286d2288" +
	"9064f4aeeb150359b9425f1da51b3a5c939018555d13ac42c565a0603786a919328f3267" +
	"09dce52c22ad958ecb7873b9771d1148b1c4be2efe80ba868919fc9f68b6090c2f33c156" +
	"d67156e42766a50b5d51e79637b7e58af74c2a951b1e642fa7741fec982cc937de37eff5" +
	"9e2005d5939bfc031589ca143e6e8ab83f40ee08cc20a6b4a95a318352c28d18528dcaf9" +
	"66705de17afa19d6e8ae91ddf33179d16ebb6ac2c69cae8373d408ebf8c55308be6c04d9" +
	"3a25439a94299a65a709756c7a3e568be049d5c38839"

What did you see happen?

The generated OCSP response is below(in hex format).

30 81 a3 a1 1b 30 19 31  17 30 15 06 03 55 04 03
13 0e 4f 43 53 50 20 52  65 73 70 6f 6e 64 65 72
18 0f 32 30 30 39 31 31  31 30 32 33 30 30 30 30
5a 30 73 30 71 30 49 30  09 06 05 2b 0e 03 02 1a
05 00 04 14 c0 fe 02 78  fc 99 18 88 91 b3 f2 12
e9 c7 e1 b2 1a b7 bf c0  04 14 0d fc 1d f0 a9 e0
f0 1c e7 f2 b2 13 17 7e  6f 8d 15 7c d4 f6 02 10
01 7f 77 de b3 bc bb 23  5d 44 cc c7 db a6 2e 72
80 00 18 0f 32 30 31 30  30 37 30 37 31 35 30 31
30 35 5a a0 11 18 0f 32  30 31 30 30 37 30 37 31
38 33 35 31 37 5a  

The decoded data you can see https://lapo.it/asn1js/#MIGjoRswGTEXMBUGA1UEAxMOT0NTUCBSZXNwb25kZXIYDzIwMDkxMTEwMjMwMDAwWjBzMHEwSTAJBgUrDgMCGgUABBTA_gJ4_JkYiJGz8hLpx-GyGre_wAQUDfwd8Kng8Bzn8rITF35vjRV81PYCEAF_d96zvLsjXUTMx9umLnKAABgPMjAxMDA3MDcxNTAxMDVaoBEYDzIwMTAwNzA3MTgzNTE3Wg

What did you expect to see?

The RFC https://datatracker.ietf.org/doc/html/rfc5912#section-3 that governs the OCSP response->CertID->hashingAlgorithm says that the parameter (which is coming as a NULL element from the go OCSP response) should not be encoded(should not be present) in the structure for the message digest algorithms.

go OCSP response should not have the NULL param element for the hashing algorithm.

@sdash713 sdash713 changed the title import/path: issue title "x/crypto" OCSP response should not contain param element for hashingAlgorithm "x/crypto" OCSP response should not contain param element for hashingAlgorithm Aug 27, 2024
@seankhliao seankhliao changed the title "x/crypto" OCSP response should not contain param element for hashingAlgorithm x/crypto/ocsp: response should not contain param element for hashingAlgorithm Aug 27, 2024
@gopherbot gopherbot added this to the Unreleased milestone Aug 27, 2024
@prattmic
Copy link
Member

cc @golang/security

@prattmic prattmic added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 27, 2024
@AGWA
Copy link

AGWA commented Aug 28, 2024

Technically it's more correct to omit the NULL parameter, but it's common practice in the WebPKI to include it (I surveyed OCSP responses from Sectigo, Let's Encrypt, DigiCert, and Google Trust Services). RFC 4055 (which is transitively referenced by RFC 6960) explains why:

There are two possible encodings for the AlgorithmIdentifier parameters field associated with these object identifiers. The two alternatives arise from the loss of the OPTIONAL associated with the algorithm identifier parameters when the 1988 syntax for AlgorithmIdentifier was translated into the 1997 syntax. Later the OPTIONAL was recovered via a defect report, but by then many people thought that algorithm parameters were mandatory. Because of this history some implementations encode parameters as a NULL element while others omit them entirely. The correct encoding is to omit the parameters field; however, when RSASSA-PSS and RSAES-OAEP were defined, it was done using the NULL parameters rather than absent parameters.

All implementations MUST accept both NULL and absent parameters as legal and equivalent encodings.

The WebPKI has yet to precisely profile OCSP, but if it does, it will probably require the NULL parameter, just as it already does for AlgorithmIdentifiers in certificate.

Since Go targets the WebPKI, I think this should be WONTFIX.

@sdash713
Copy link
Author

@AGWA thank you for pointing out to history of the AlgorithmIdentifier parameter. I believe common OCSP responders that you are referring are built on top of golang. That may be reason we are seeing NULL parameter element in their response.

But if you see the OCSP response from OpenSSL OCSP responder, it does not have NULL parameter in the response.

golang is a new age language and it would be correct to remove the NULL parameter for hashing algorithm from OCSP response and keeping the behavior intact(NULL or empty accept) in OCSP response processing side.

@AGWA
Copy link

AGWA commented Aug 29, 2024

I'm curious why you believe Sectigo and DigiCert's OCSP responders use Go? And it's not just them - Microsoft, GlobalSign, Entrust, Identrust, ssl.com also include the NULL parameter in OCSP responses.

But the more important point is that WebPKI policy already requires the NULL parameter in certificates, and accordingly Go diverges from OpenSSL's behavior when encoding certificates (see #38014). While there is not currently the same policy requirement for OCSP, there may be in the future, since the WebPKI prefers having one encoding for things. For AlgorithmIdentifiers, that means including NULL parameters.

Note that omitting the parameters is a "SHOULD", meaning Go can ignore it if it has valid reasons to do so. Consistency with certificate encoding, consistency with WebPKI practice, and anticipation of future WebPKI policy requirements are all valid reasons to ignore the requirement.

@rolandshoemaker
Copy link
Member

Distilling #38014, RFC 4055 clarifies the encoding for CRLs and certificates, but didn't for whatever reason do the same for OCSP. We are just being consistent, and based on the logic in 4055, I think it makes sense to do the same across the board.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

8 participants
@AGWA @prattmic @rolandshoemaker @gopherbot @sdash713 @gabyhelp and others