Fix parseCertificateInfo possibly in dead loop
This commit is contained in:
		
							parent
							
								
									c92153c97e
								
							
						
					
					
						commit
						41a6d1b701
					
				
					 3 changed files with 139 additions and 2 deletions
				
			
		|  | @ -367,7 +367,7 @@ class Monitor extends BeanModel { | |||
|                 await Monitor.sendNotification(isFirstBeat, this, bean); | ||||
| 
 | ||||
|                 // Clear Status Page Cache
 | ||||
|                 debug(`[${this.name}] Check isImportant`); | ||||
|                 debug(`[${this.name}] apicache clear`); | ||||
|                 apicache.clear(); | ||||
| 
 | ||||
|             } else { | ||||
|  |  | |||
|  | @ -201,8 +201,13 @@ const getDaysRemaining = (validFrom, validTo) => { | |||
| // param: info -  the chain obtained from getPeerCertificate()
 | ||||
| const parseCertificateInfo = function (info) { | ||||
|     let link = info; | ||||
|     let i = 0; | ||||
| 
 | ||||
|     const existingList = {}; | ||||
| 
 | ||||
|     while (link) { | ||||
|         debug(`[${i}] ${link.fingerprint}`); | ||||
| 
 | ||||
|         if (!link.valid_from || !link.valid_to) { | ||||
|             break; | ||||
|         } | ||||
|  | @ -210,15 +215,24 @@ const parseCertificateInfo = function (info) { | |||
|         link.validFor = link.subjectaltname?.replace(/DNS:|IP Address:/g, "").split(", "); | ||||
|         link.daysRemaining = getDaysRemaining(new Date(), link.validTo); | ||||
| 
 | ||||
|         existingList[link.fingerprint] = true; | ||||
| 
 | ||||
|         // Move up the chain until loop is encountered
 | ||||
|         if (link.issuerCertificate == null) { | ||||
|             break; | ||||
|         } else if (link.fingerprint == link.issuerCertificate.fingerprint) { | ||||
|         } else if (link.issuerCertificate.fingerprint in existingList) { | ||||
|             debug(`[Last] ${link.issuerCertificate.fingerprint}`); | ||||
|             link.issuerCertificate = null; | ||||
|             break; | ||||
|         } else { | ||||
|             link = link.issuerCertificate; | ||||
|         } | ||||
| 
 | ||||
|         // Should be no use, but just in case.
 | ||||
|         if (i > 500) { | ||||
|             throw new Error("Dead loop occurred in parseCertificateInfo"); | ||||
|         } | ||||
|         i++; | ||||
|     } | ||||
| 
 | ||||
|     return info; | ||||
|  | @ -228,6 +242,7 @@ exports.checkCertificate = function (res) { | |||
|     const info = res.request.res.socket.getPeerCertificate(true); | ||||
|     const valid = res.request.res.socket.authorized || false; | ||||
| 
 | ||||
|     console.log("Parsing Certificate Info"); | ||||
|     const parsedInfo = parseCertificateInfo(info); | ||||
| 
 | ||||
|     return { | ||||
|  |  | |||
|  | @ -1,4 +1,125 @@ | |||
| const { genSecret, sleep } = require("../src/util"); | ||||
| const utilServerRewire = require("../server/util-server"); | ||||
| 
 | ||||
| describe("Test parseCertificateInfo", () => { | ||||
|     it("should handle undefined", async () => { | ||||
|         const parseCertificateInfo = utilServerRewire.__get__("parseCertificateInfo"); | ||||
|         const info = parseCertificateInfo(undefined); | ||||
|         expect(info).toEqual(undefined); | ||||
|     }, 5000); | ||||
| 
 | ||||
|     it("should handle normal cert chain", async () => { | ||||
|         const parseCertificateInfo = utilServerRewire.__get__("parseCertificateInfo"); | ||||
| 
 | ||||
|         const chain1 = { | ||||
|             fingerprint: "CF:2C:F3:6A:FE:6B:10:EC:44:77:C8:95:BB:96:2E:06:1F:0E:15:DA", | ||||
|             valid_from: "Oct 22 12:00:00 2013 GMT", | ||||
|             valid_to: "Oct 22 12:00:00 2028 GMT", | ||||
|             subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net", | ||||
|         }; | ||||
| 
 | ||||
|         const chain2 = { | ||||
|             fingerprint: "A0:31:C4:67:82:E6:E6:C6:62:C2:C8:7C:76:DA:9A:A6:2C:CA:BD:8E", | ||||
|             valid_from: "Oct 22 12:00:00 2013 GMT", | ||||
|             valid_to: "Oct 22 12:00:00 2028 GMT", | ||||
|             subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net", | ||||
|         }; | ||||
| 
 | ||||
|         const chain3 = { | ||||
|             fingerprint: "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25", | ||||
|             valid_from: "Oct 22 12:00:00 2013 GMT", | ||||
|             valid_to: "Oct 22 12:00:00 2028 GMT", | ||||
|             subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net", | ||||
|         }; | ||||
| 
 | ||||
|         chain1.issuerCertificate = chain2; | ||||
|         chain2.issuerCertificate = chain3; | ||||
|         chain3.issuerCertificate = chain3; | ||||
| 
 | ||||
|         const info = parseCertificateInfo(chain1); | ||||
|         expect(chain1).toEqual(info); | ||||
|     }, 5000); | ||||
| 
 | ||||
|     it("should handle cert chain with strange circle", async () => { | ||||
|         const parseCertificateInfo = utilServerRewire.__get__("parseCertificateInfo"); | ||||
| 
 | ||||
|         const chain1 = { | ||||
|             fingerprint: "CF:2C:F3:6A:FE:6B:10:EC:44:77:C8:95:BB:96:2E:06:1F:0E:15:DA", | ||||
|             valid_from: "Oct 22 12:00:00 2013 GMT", | ||||
|             valid_to: "Oct 22 12:00:00 2028 GMT", | ||||
|             subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net", | ||||
|         }; | ||||
| 
 | ||||
|         const chain2 = { | ||||
|             fingerprint: "A0:31:C4:67:82:E6:E6:C6:62:C2:C8:7C:76:DA:9A:A6:2C:CA:BD:8E", | ||||
|             valid_from: "Oct 22 12:00:00 2013 GMT", | ||||
|             valid_to: "Oct 22 12:00:00 2028 GMT", | ||||
|             subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net", | ||||
|         }; | ||||
| 
 | ||||
|         const chain3 = { | ||||
|             fingerprint: "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25", | ||||
|             valid_from: "Oct 22 12:00:00 2013 GMT", | ||||
|             valid_to: "Oct 22 12:00:00 2028 GMT", | ||||
|             subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net", | ||||
|         }; | ||||
| 
 | ||||
|         const chain4 = { | ||||
|             fingerprint: "haha", | ||||
|             valid_from: "Oct 22 12:00:00 2013 GMT", | ||||
|             valid_to: "Oct 22 12:00:00 2028 GMT", | ||||
|             subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net", | ||||
|         }; | ||||
| 
 | ||||
|         chain1.issuerCertificate = chain2; | ||||
|         chain2.issuerCertificate = chain3; | ||||
|         chain3.issuerCertificate = chain4; | ||||
|         chain4.issuerCertificate = chain2; | ||||
| 
 | ||||
|         const info = parseCertificateInfo(chain1); | ||||
|         expect(chain1).toEqual(info); | ||||
|     }, 5000); | ||||
| 
 | ||||
|     it("should handle cert chain with last undefined (should be happen in real, but just in case)", async () => { | ||||
|         const parseCertificateInfo = utilServerRewire.__get__("parseCertificateInfo"); | ||||
| 
 | ||||
|         const chain1 = { | ||||
|             fingerprint: "CF:2C:F3:6A:FE:6B:10:EC:44:77:C8:95:BB:96:2E:06:1F:0E:15:DA", | ||||
|             valid_from: "Oct 22 12:00:00 2013 GMT", | ||||
|             valid_to: "Oct 22 12:00:00 2028 GMT", | ||||
|             subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net", | ||||
|         }; | ||||
| 
 | ||||
|         const chain2 = { | ||||
|             fingerprint: "A0:31:C4:67:82:E6:E6:C6:62:C2:C8:7C:76:DA:9A:A6:2C:CA:BD:8E", | ||||
|             valid_from: "Oct 22 12:00:00 2013 GMT", | ||||
|             valid_to: "Oct 22 12:00:00 2028 GMT", | ||||
|             subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net", | ||||
|         }; | ||||
| 
 | ||||
|         const chain3 = { | ||||
|             fingerprint: "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25", | ||||
|             valid_from: "Oct 22 12:00:00 2013 GMT", | ||||
|             valid_to: "Oct 22 12:00:00 2028 GMT", | ||||
|             subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net", | ||||
|         }; | ||||
| 
 | ||||
|         const chain4 = { | ||||
|             fingerprint: "haha", | ||||
|             valid_from: "Oct 22 12:00:00 2013 GMT", | ||||
|             valid_to: "Oct 22 12:00:00 2028 GMT", | ||||
|             subjectaltname: "DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net", | ||||
|         }; | ||||
| 
 | ||||
|         chain1.issuerCertificate = chain2; | ||||
|         chain2.issuerCertificate = chain3; | ||||
|         chain3.issuerCertificate = chain4; | ||||
|         chain4.issuerCertificate = undefined; | ||||
| 
 | ||||
|         const info = parseCertificateInfo(chain1); | ||||
|         expect(chain1).toEqual(info); | ||||
|     }, 5000); | ||||
| }); | ||||
| 
 | ||||
| describe("Test genSecret", () => { | ||||
| 
 | ||||
|  | @ -42,3 +163,4 @@ describe("Test reset-password", () => { | |||
|         await require("../extra/reset-password").main(); | ||||
|     }, 120000); | ||||
| }); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue