瀏覽代碼

go.crypto/ocsp: pass in the issuing certificate.

Paul van Brouwershaven pointed out that it would be better to pass in
the issuing certificate and have the verification be done in the OCSP
package than to expect the caller to deal with the difference between
responses with and without a responder certificate.

R=golang-dev, dayveday, paul
CC=golang-dev
https://golang.org/cl/11220043
Adam Langley 12 年之前
父節點
當前提交
16d76afb29
共有 2 個文件被更改,包括 75 次插入5 次删除
  1. 14 3
      ocsp/ocsp.go
  2. 61 2
      ocsp/ocsp_test.go

+ 14 - 3
ocsp/ocsp.go

@@ -171,9 +171,10 @@ func (p ParseError) Error() string {
 
 // ParseResponse parses an OCSP response in DER form. It only supports
 // responses for a single certificate. If the response contains a certificate
-// then the signature over the response is checked. Invalid signatures or parse
-// failures will result in a ParseError.
-func ParseResponse(bytes []byte) (*Response, error) {
+// 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.
+func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
 	var resp responseASN1
 	rest, err := asn1.Unmarshal(bytes, &resp)
 	if err != nil {
@@ -220,6 +221,16 @@ func ParseResponse(bytes []byte) (*Response, error) {
 		if err := ret.CheckSignatureFrom(ret.Certificate); err != nil {
 			return nil, ParseError("bad OCSP signature")
 		}
+
+		if issuer != nil {
+			if err := issuer.CheckSignature(ret.Certificate.SignatureAlgorithm, ret.Certificate.RawTBSCertificate, ret.Certificate.Signature); err != nil {
+				return nil, ParseError("bad signature on embedded certificate")
+			}
+		}
+	} else if issuer != nil {
+		if err := ret.CheckSignatureFrom(issuer); err != nil {
+			return nil, ParseError("bad OCSP signature")
+		}
 	}
 
 	r := basicResp.TBSResponseData.Responses[0]

+ 61 - 2
ocsp/ocsp_test.go

@@ -16,7 +16,7 @@ import (
 
 func TestOCSPDecode(t *testing.T) {
 	responseBytes, _ := hex.DecodeString(ocspResponseHex)
-	resp, err := ParseResponse(responseBytes)
+	resp, err := ParseResponse(responseBytes, nil)
 	if err != nil {
 		t.Error(err)
 	}
@@ -52,12 +52,25 @@ func TestOCSPDecode(t *testing.T) {
 
 func TestOCSPDecodeWithoutCert(t *testing.T) {
 	responseBytes, _ := hex.DecodeString(ocspResponseWithoutCertHex)
-	_, err := ParseResponse(responseBytes)
+	_, err := ParseResponse(responseBytes, nil)
 	if err != nil {
 		t.Error(err)
 	}
 }
 
+func TestOCSPSignature(t *testing.T) {
+	issuerCert, _ := hex.DecodeString(startComHex)
+	issuer, err := x509.ParseCertificate(issuerCert)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	response, _ := hex.DecodeString(ocspResponseHex)
+	if _, err := ParseResponse(response, issuer); err != nil {
+		t.Error(err)
+	}
+}
+
 func TestOCSPRequest(t *testing.T) {
 	leafCert, _ := hex.DecodeString(leafCertHex)
 	cert, err := x509.ParseCertificate(leafCert)
@@ -140,6 +153,52 @@ const ocspResponseHex = "308206bc0a0100a08206b5308206b106092b0601050507300101048
 	"a1d24ce16e41a9941568fec5b42771e118f16c106a54ccc339a4b02166445a167902e75e" +
 	"6d8620b0825dcd18a069b90fd851d10fa8effd409deec02860d26d8d833f304b10669b42"
 
+const startComHex = "308206343082041ca003020102020118300d06092a864886f70d0101050500307d310b30" +
+	"0906035504061302494c31163014060355040a130d5374617274436f6d204c74642e312b" +
+	"3029060355040b1322536563757265204469676974616c20436572746966696361746520" +
+	"5369676e696e6731293027060355040313205374617274436f6d20436572746966696361" +
+	"74696f6e20417574686f72697479301e170d3037313032343230353431375a170d313731" +
+	"3032343230353431375a30818c310b300906035504061302494c31163014060355040a13" +
+	"0d5374617274436f6d204c74642e312b3029060355040b13225365637572652044696769" +
+	"74616c204365727469666963617465205369676e696e67313830360603550403132f5374" +
+	"617274436f6d20436c6173732031205072696d61727920496e7465726d65646961746520" +
+	"53657276657220434130820122300d06092a864886f70d01010105000382010f00308201" +
+	"0a0282010100b689c6acef09527807ac9263d0f44418188480561f91aee187fa3250b4d3" +
+	"4706f0e6075f700e10f71dc0ce103634855a0f92ac83c6ac58523fba38e8fce7a724e240" +
+	"a60876c0926e9e2a6d4d3f6e61200adb59ded27d63b33e46fefa215118d7cd30a6ed076e" +
+	"3b7087b4f9faebee823c056f92f7a4dc0a301e9373fe07cad75f809d225852ae06da8b87" +
+	"2369b0e42ad8ea83d2bdf371db705a280faf5a387045123f304dcd3baf17e50fcba0a95d" +
+	"48aab16150cb34cd3c5cc30be810c08c9bf0030362feb26c3e720eee1c432ac9480e5739" +
+	"c43121c810c12c87fe5495521f523c31129b7fe7c0a0a559d5e28f3ef0d5a8e1d77031a9" +
+	"c4b3cfaf6d532f06f4a70203010001a38201ad308201a9300f0603551d130101ff040530" +
+	"030101ff300e0603551d0f0101ff040403020106301d0603551d0e04160414eb4234d098" +
+	"b0ab9ff41b6b08f7cc642eef0e2c45301f0603551d230418301680144e0bef1aa4405ba5" +
+	"17698730ca346843d041aef2306606082b06010505070101045a3058302706082b060105" +
+	"05073001861b687474703a2f2f6f6373702e737461727473736c2e636f6d2f6361302d06" +
+	"082b060105050730028621687474703a2f2f7777772e737461727473736c2e636f6d2f73" +
+	"667363612e637274305b0603551d1f045430523027a025a0238621687474703a2f2f7777" +
+	"772e737461727473736c2e636f6d2f73667363612e63726c3027a025a023862168747470" +
+	"3a2f2f63726c2e737461727473736c2e636f6d2f73667363612e63726c3081800603551d" +
+	"20047930773075060b2b0601040181b5370102013066302e06082b060105050702011622" +
+	"687474703a2f2f7777772e737461727473736c2e636f6d2f706f6c6963792e7064663034" +
+	"06082b060105050702011628687474703a2f2f7777772e737461727473736c2e636f6d2f" +
+	"696e7465726d6564696174652e706466300d06092a864886f70d01010505000382020100" +
+	"2109493ea5886ee00b8b48da314d8ff75657a2e1d36257e9b556f38545753be5501f048b" +
+	"e6a05a3ee700ae85d0fbff200364cbad02e1c69172f8a34dd6dee8cc3fa18aa2e37c37a7" +
+	"c64f8f35d6f4d66e067bdd21d9cf56ffcb302249fe8904f385e5aaf1e71fe875904dddf9" +
+	"46f74234f745580c110d84b0c6da5d3ef9019ee7e1da5595be741c7bfc4d144fac7e5547" +
+	"7d7bf4a50d491e95e8f712c1ccff76a62547d0f37535be97b75816ebaa5c786fec5330af" +
+	"ea044dcca902e3f0b60412f630b1113d904e5664d7dc3c435f7339ef4baf87ebf6fe6888" +
+	"4472ead207c669b0c1a18bef1749d761b145485f3b2021e95bb2ccf4d7e931f50b15613b" +
+	"7a94e3ebd9bc7f94ae6ae3626296a8647cb887f399327e92a252bebbf865cfc9f230fc8b" +
+	"c1c2a696d75f89e15c3480f58f47072fb491bfb1a27e5f4b5ad05b9f248605515a690365" +
+	"434971c5e06f94346bf61bd8a9b04c7e53eb8f48dfca33b548fa364a1a53a6330cd089cd" +
+	"4915cd89313c90c072d7654b52358a461144b93d8e2865a63e799e5c084429adb035112e" +
+	"214eb8d2e7103e5d8483b3c3c2e4d2c6fd094b7409ddf1b3d3193e800da20b19f038e7c5" +
+	"c2afe223db61e29d5c6e2089492e236ab262c145b49faf8ba7f1223bf87de290d07a19fb" +
+	"4a4ce3d27d5f4a8303ed27d6239e6b8db459a2d9ef6c8229dd75193c3f4c108defbb7527" +
+	"d2ae83a7a8ce5ba7"
+
 const ocspResponseWithoutCertHex = "308201d40a0100a08201cd308201c906092b0601050507300101048201ba3082" +
 	"01b630819fa2160414884451ff502a695e2d88f421bad90cf2cecbea7c180f3230313330" +
 	"3631383037323434335a30743072304a300906052b0e03021a0500041448b60d38238df8" +