x/crypto/ocsp: Accept status for multiple certificates in response

This change add a function select to correct response from a responder
that includes multiple certificates in the case the server uses response
pre-generation.

RFC6960 section 4.2.2 states:

"The response MUST include a SingleResponse for each certificate in
   the request.  The response SHOULD NOT include any additional
   SingleResponse elements, but, for example, OCSP responders that
   pre-generate status responses might include additional SingleResponse
   elements if necessary to improve response pre-generation performance
   or cache efficiency (according to [RFC5019], Section 2.2.1)."

Change-Id: I39eeaa3daf16a7d7eb030e34229f16cf4295f9d7
Reviewed-on: https://go-review.googlesource.com/10611
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/ocsp/ocsp.go b/ocsp/ocsp.go
index a57e5f4..2c7e57a 100644
--- a/ocsp/ocsp.go
+++ b/ocsp/ocsp.go
@@ -437,6 +437,18 @@
 // Invalid signatures or parse failures will result in a ParseError. Error
 // responses will result in a ResponseError.
 func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
+	return ParseResponseForCert(bytes, nil, issuer)
+}
+
+// ParseResponseForCert parses an OCSP response in DER form and searches for a
+// Response relating to cert. If such a Response is found and the OCSP response
+// contains a certificate then the signature over the response is checked. If
+// issuer is not nil then it will be used to validate the signature or embedded
+// certificate.
+//
+// Invalid signatures or parse failures will result in a ParseError. Error
+// responses will result in a ResponseError.
+func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Response, error) {
 	var resp responseASN1
 	rest, err := asn1.Unmarshal(bytes, &resp)
 	if err != nil {
@@ -464,7 +476,7 @@
 		return nil, ParseError("OCSP response contains bad number of certificates")
 	}
 
-	if len(basicResp.TBSResponseData.Responses) != 1 {
+	if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 {
 		return nil, ParseError("OCSP response contains bad number of responses")
 	}
 
@@ -495,7 +507,13 @@
 		}
 	}
 
-	r := basicResp.TBSResponseData.Responses[0]
+	var r singleResponse
+	for _, resp := range basicResp.TBSResponseData.Responses {
+		if cert == nil || cert.SerialNumber.Cmp(resp.CertID.SerialNumber) == 0 {
+			r = resp
+			break
+		}
+	}
 
 	for _, ext := range r.SingleExtensions {
 		if ext.Critical {
diff --git a/ocsp/ocsp_test.go b/ocsp/ocsp_test.go
index ae17ca2..f66489a 100644
--- a/ocsp/ocsp_test.go
+++ b/ocsp/ocsp_test.go
@@ -278,6 +278,24 @@
 	}
 }
 
+func TestOCSPDecodeMultiResponse(t *testing.T) {
+	inclCert, _ := hex.DecodeString(ocspMultiResponseCertHex)
+	cert, err := x509.ParseCertificate(inclCert)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	responseBytes, _ := hex.DecodeString(ocspMultiResponseHex)
+	resp, err := ParseResponseForCert(responseBytes, cert, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if resp.SerialNumber.Cmp(cert.SerialNumber) != 0 {
+		t.Errorf("resp.SerialNumber: got %x, want %x", resp.SerialNumber, cert.SerialNumber)
+	}
+}
+
 // This OCSP response was taken from Thawte's public OCSP responder.
 // To recreate:
 //   $ openssl s_client -tls1 -showcerts -servername www.google.com -connect www.google.com:443
@@ -475,6 +493,169 @@
 	"e17afa19d6e8ae91ddf33179d16ebb6ac2c69cae8373d408ebf8c55308be6c04d93a2543" +
 	"9a94299a65a709756c7a3e568be049d5c38839"
 
+const ocspMultiResponseHex = "30820ee60a0100a0820edf30820edb06092b060105050730010104820ecc30820ec83082" +
+	"0839a216041445ac2ecd75f53f1cf6e4c51d3de0047ad0aa7465180f3230313530363032" +
+	"3130303033305a3082080c3065303d300906052b0e03021a05000414f7452a0080601527" +
+	"72e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f0204" +
+	"5456656a8000180f32303135303630323039303230375aa011180f323031353036303331" +
+	"30303033305a3065303d300906052b0e03021a05000414f7452a008060152772e4a135e7" +
+	"6e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f02045456656b80" +
+	"00180f32303135303630323039303230375aa011180f3230313530363033313030303330" +
+	"5a3065303d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0" +
+	"f1580414edd8f2ee977252853a330b297a18f5c993853b3f02045456656c8000180f3230" +
+	"3135303630323039303230375aa011180f32303135303630333130303033305a3065303d" +
+	"300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414ed" +
+	"d8f2ee977252853a330b297a18f5c993853b3f02045456656d8000180f32303135303630" +
+	"323039303230375aa011180f32303135303630333130303033305a3065303d300906052b" +
+	"0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee9772" +
+	"52853a330b297a18f5c993853b3f02045456656e8000180f323031353036303230393032" +
+	"30375aa011180f32303135303630333130303033305a3065303d300906052b0e03021a05" +
+	"000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b" +
+	"297a18f5c993853b3f02045456656f8000180f32303135303630323039303230375aa011" +
+	"180f32303135303630333130303033305a3065303d300906052b0e03021a05000414f745" +
+	"2a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c9" +
+	"93853b3f0204545665708000180f32303135303630323039303230375aa011180f323031" +
+	"35303630333130303033305a3065303d300906052b0e03021a05000414f7452a00806015" +
+	"2772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f02" +
+	"04545665718000180f32303135303630323039303230375aa011180f3230313530363033" +
+	"3130303033305a3065303d300906052b0e03021a05000414f7452a008060152772e4a135" +
+	"e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f020454566572" +
+	"8000180f32303135303630323039303230375aa011180f32303135303630333130303033" +
+	"305a3065303d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fd" +
+	"e0f1580414edd8f2ee977252853a330b297a18f5c993853b3f0204545665738000180f32" +
+	"303135303630323039303230375aa011180f32303135303630333130303033305a306530" +
+	"3d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414" +
+	"edd8f2ee977252853a330b297a18f5c993853b3f0204545665748000180f323031353036" +
+	"30323039303230375aa011180f32303135303630333130303033305a3065303d30090605" +
+	"2b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee97" +
+	"7252853a330b297a18f5c993853b3f0204545665758000180f3230313530363032303930" +
+	"3230375aa011180f32303135303630333130303033305a3065303d300906052b0e03021a" +
+	"05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a33" +
+	"0b297a18f5c993853b3f0204545665768000180f32303135303630323039303230375aa0" +
+	"11180f32303135303630333130303033305a3065303d300906052b0e03021a05000414f7" +
+	"452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5" +
+	"c993853b3f0204545665778000180f32303135303630323039303230375aa011180f3230" +
+	"3135303630333130303033305a3065303d300906052b0e03021a05000414f7452a008060" +
+	"152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f" +
+	"0204545665788000180f32303135303630323039303230375aa011180f32303135303630" +
+	"333130303033305a3065303d300906052b0e03021a05000414f7452a008060152772e4a1" +
+	"35e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f0204545665" +
+	"798000180f32303135303630323039303230375aa011180f323031353036303331303030" +
+	"33305a3065303d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52" +
+	"fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f02045456657a8000180f" +
+	"32303135303630323039303230375aa011180f32303135303630333130303033305a3065" +
+	"303d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f15804" +
+	"14edd8f2ee977252853a330b297a18f5c993853b3f02045456657b8000180f3230313530" +
+	"3630323039303230375aa011180f32303135303630333130303033305a3065303d300906" +
+	"052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee" +
+	"977252853a330b297a18f5c993853b3f02045456657c8000180f32303135303630323039" +
+	"303230375aa011180f32303135303630333130303033305a3065303d300906052b0e0302" +
+	"1a05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a" +
+	"330b297a18f5c993853b3f02045456657d8000180f32303135303630323039303230375a" +
+	"a011180f32303135303630333130303033305a300d06092a864886f70d01010505000382" +
+	"01010016b73b92859979f27d15eb018cf069eed39c3d280213565f3026de11ba15bdb94d" +
+	"764cf2d0fdd204ef926c588d7b183483c8a2b1995079c7ed04dcefcc650c1965be4b6832" +
+	"a8839e832f7f60f638425eccdf9bc3a81fbe700fda426ddf4f06c29bee431bbbe81effda" +
+	"a60b7da5b378f199af2f3c8380be7ba6c21c8e27124f8a4d8989926aea19055700848d33" +
+	"799e833512945fd75364edbd2dd18b783c1e96e332266b17979a0b88c35b43f47c87c493" +
+	"19155056ad8dbbae5ff2afad3c0e1c69ed111206ffda49875e8e4efc0926264823bc4423" +
+	"c8a002f34288c4bc22516f98f54fc609943721f590ddd8d24f989457526b599b0eb75cb5" +
+	"a80da1ad93a621a08205733082056f3082056b30820453a0030201020204545638c4300d" +
+	"06092a864886f70d01010b0500308182310b300906035504061302555331183016060355" +
+	"040a130f552e532e20476f7665726e6d656e7431233021060355040b131a446570617274" +
+	"6d656e74206f662074686520547265617375727931223020060355040b13194365727469" +
+	"6669636174696f6e20417574686f7269746965733110300e060355040b13074f43494f20" +
+	"4341301e170d3135303332303131353531335a170d3135303633303034303030305a3081" +
+	"98310b300906035504061302555331183016060355040a130f552e532e20476f7665726e" +
+	"6d656e7431233021060355040b131a4465706172746d656e74206f662074686520547265" +
+	"617375727931223020060355040b131943657274696669636174696f6e20417574686f72" +
+	"69746965733110300e060355040b13074f43494f204341311430120603550403130b4f43" +
+	"5350205369676e657230820122300d06092a864886f70d01010105000382010f00308201" +
+	"0a0282010100c1b6fe1ba1ad50bb98c855811acbd67fe68057f48b8e08d3800e7f2c51b7" +
+	"9e20551934971fd92b9c9e6c49453097927cba83a94c0b2fea7124ba5ac442b38e37dba6" +
+	"7303d4962dd7d92b22a04b0e0e182e9ea67620b1c6ce09ee607c19e0e6e3adae81151db1" +
+	"2bb7f706149349a292e21c1eb28565b6839df055e1a838a772ff34b5a1452618e2c26042" +
+	"705d53f0af4b57aae6163f58216af12f3887813fe44b0321827b3a0c52b0e47d0aab94a2" +
+	"f768ab0ba3901d22f8bb263823090b0e37a7f8856db4b0d165c42f3aa7e94f5f6ce1855e" +
+	"98dc57adea0ae98ad39f67ecdec00b88685566e9e8d69f6cefb6ddced53015d0d3b862bc" +
+	"be21f3d72251eefcec730203010001a38201cf308201cb300e0603551d0f0101ff040403" +
+	"020780306b0603551d2004643062300c060a60864801650302010502300c060a60864801" +
+	"650302010503300c060a60864801650302010504300c060a60864801650302010507300c" +
+	"060a60864801650302010508300c060a6086480165030201030d300c060a608648016503" +
+	"020103113081e506082b060105050701010481d83081d5303006082b0601050507300286" +
+	"24687474703a2f2f706b692e74726561732e676f762f746f63615f65655f6169612e7037" +
+	"633081a006082b060105050730028681936c6461703a2f2f6c6461702e74726561732e67" +
+	"6f762f6f753d4f43494f25323043412c6f753d43657274696669636174696f6e25323041" +
+	"7574686f7269746965732c6f753d4465706172746d656e742532306f6625323074686525" +
+	"323054726561737572792c6f3d552e532e253230476f7665726e6d656e742c633d55533f" +
+	"634143657274696669636174653b62696e61727930130603551d25040c300a06082b0601" +
+	"0505070309300f06092b060105050730010504020500301f0603551d23041830168014a2" +
+	"13a8e5c607546c243d4eb72b27a2a7711ab5af301d0603551d0e0416041451f98046818a" +
+	"e46d953ac90c210ccfaa1a06980c300d06092a864886f70d01010b050003820101003a37" +
+	"0b301d14ffdeb370883639bec5ae6f572dcbddadd672af16ee2a8303316b14e1fbdca8c2" +
+	"8f4bad9c7b1410250e149c14e9830ca6f17370a8d13151205d956e28c141cc0500379596" +
+	"c5b9239fcfa3d2de8f1d4f1a2b1bf2d1851bed1c86012ee8135bdc395cd4496ce69fadd0" +
+	"3b682b90350ca7b4f458190b7a0ab5c33a04cf1347a77d541877a380a4c94988c5658908" +
+	"44fdc22637a72b9fa410333e2caf969477f9fe07f50e3681c204fb3bf073b9da01cd8d91" +
+	"8044c40b1159955af12a3263ab1d34119d7f59bfa6cae88ed058addc4e08250263f8f836" +
+	"2f5bdffd45636fea7474c60a55c535954477b2f286e1b2535f0dd12c162f1b353c370e08" +
+	"be67"
+
+const ocspMultiResponseCertHex = "308207943082067ca003020102020454566573300d06092a864886f70d01010b05003081" +
+	"82310b300906035504061302555331183016060355040a130f552e532e20476f7665726e" +
+	"6d656e7431233021060355040b131a4465706172746d656e74206f662074686520547265" +
+	"617375727931223020060355040b131943657274696669636174696f6e20417574686f72" +
+	"69746965733110300e060355040b13074f43494f204341301e170d313530343130313535" +
+	"3733385a170d3138303431303136323733385a30819d310b300906035504061302555331" +
+	"183016060355040a130f552e532e20476f7665726e6d656e7431233021060355040b131a" +
+	"4465706172746d656e74206f662074686520547265617375727931253023060355040b13" +
+	"1c427572656175206f66207468652046697363616c20536572766963653110300e060355" +
+	"040b130744657669636573311630140603550403130d706b692e74726561732e676f7630" +
+	"820122300d06092a864886f70d01010105000382010f003082010a0282010100c7273623" +
+	"8c49c48bf501515a2490ef6e5ae0c06e0ad2aa9a6bb77f3d0370d846b2571581ebf38fd3" +
+	"1948daad3dec7a4da095f1dcbe9654e65bcf7acdfd4ee802421dad9b90536c721d2bca58" +
+	"8413e6bfd739a72470560bb7d64f9a09284f90ff8af1d5a3c5c84d0f95a00f9c6d988dd0" +
+	"d87f1d0d3344580901c955139f54d09de0acdbd3322b758cb0c58881bf04913243401f44" +
+	"013fd9f6d8348044cc8bb0a71978ad93366b2a4687a5274b2ee07d0fb40225453eb244ed" +
+	"b20152251ac77c59455260ff07eeceb3cb3c60fb8121cf92afd3daa2a4650e1942ccb555" +
+	"de10b3d481feb299838ef05d0fd1810b146753472ae80da65dd34da25ca1f89971f10039" +
+	"0203010001a38203f3308203ef300e0603551d0f0101ff0404030205a030170603551d20" +
+	"0410300e300c060a60864801650302010503301106096086480186f84201010404030206" +
+	"4030130603551d25040c300a06082b060105050703013082010806082b06010505070101" +
+	"0481fb3081f8303006082b060105050730028624687474703a2f2f706b692e7472656173" +
+	"2e676f762f746f63615f65655f6169612e7037633081a006082b06010505073002868193" +
+	"6c6461703a2f2f6c6461702e74726561732e676f762f6f753d4f43494f25323043412c6f" +
+	"753d43657274696669636174696f6e253230417574686f7269746965732c6f753d446570" +
+	"6172746d656e742532306f6625323074686525323054726561737572792c6f3d552e532e" +
+	"253230476f7665726e6d656e742c633d55533f634143657274696669636174653b62696e" +
+	"617279302106082b060105050730018615687474703a2f2f6f6373702e74726561732e67" +
+	"6f76307b0603551d1104743072811c6373612d7465616d4066697363616c2e7472656173" +
+	"7572792e676f768210706b692e74726561737572792e676f768210706b692e64696d632e" +
+	"6468732e676f76820d706b692e74726561732e676f76811f6563622d686f7374696e6740" +
+	"66697363616c2e74726561737572792e676f76308201890603551d1f048201803082017c" +
+	"3027a025a0238621687474703a2f2f706b692e74726561732e676f762f4f43494f5f4341" +
+	"332e63726c3082014fa082014ba0820147a48197308194310b3009060355040613025553" +
+	"31183016060355040a130f552e532e20476f7665726e6d656e7431233021060355040b13" +
+	"1a4465706172746d656e74206f662074686520547265617375727931223020060355040b" +
+	"131943657274696669636174696f6e20417574686f7269746965733110300e060355040b" +
+	"13074f43494f2043413110300e0603550403130743524c313430398681aa6c6461703a2f" +
+	"2f6c6461702e74726561732e676f762f636e3d43524c313430392c6f753d4f43494f2532" +
+	"3043412c6f753d43657274696669636174696f6e253230417574686f7269746965732c6f" +
+	"753d4465706172746d656e742532306f6625323074686525323054726561737572792c6f" +
+	"3d552e532e253230476f7665726e6d656e742c633d55533f636572746966696361746552" +
+	"65766f636174696f6e4c6973743b62696e617279302b0603551d1004243022800f323031" +
+	"35303431303135353733385a810f32303138303431303136323733385a301f0603551d23" +
+	"041830168014a213a8e5c607546c243d4eb72b27a2a7711ab5af301d0603551d0e041604" +
+	"14b0869c12c293914cd460e33ed43e6c5a26e0d68f301906092a864886f67d074100040c" +
+	"300a1b0456382e31030203a8300d06092a864886f70d01010b050003820101004968d182" +
+	"8f9efdc147e747bb5dda15536a42a079b32d3d7f87e619b483aeee70b7e26bda393c6028" +
+	"7c733ecb468fe8b8b11bf809ff76add6b90eb25ad8d3a1052e43ee281e48a3a1ebe7efb5" +
+	"9e2c4a48765dedeb23f5346242145786cc988c762d230d28dd33bf4c2405d80cbb2cb1d6" +
+	"4c8f10ba130d50cb174f6ffb9cfc12808297a2cefba385f4fad170f39b51ebd87c12abf9" +
+	"3c51fc000af90d8aaba78f48923908804a5eb35f617ccf71d201e3708a559e6d16f9f13e" +
+	"074361eb9007e28d86bb4e0bfa13aad0e9ddd9124e84519de60e2fc6040b18d9fd602b02" +
+	"684b4c071c3019fc842197d00c120c41654bcbfbc4a096a1c637b79112b81ce1fa3899f9"
+
 const ocspRequestHex = "3051304f304d304b3049300906052b0e03021a05000414c0fe0278fc99188891b3f212e9" +
 	"c7e1b21ab7bfc004140dfc1df0a9e0f01ce7f2b213177e6f8d157cd4f60210017f77deb3" +
 	"bcbb235d44ccc7dba62e72"