-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ownership: upgrade sha1 key algorithms
- Loading branch information
Showing
4 changed files
with
235 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Private-key-format: v1.3 | ||
Algorithm: 5 (RSASHA1) | ||
Modulus: vExWE8PxRiW0zoaec/vit/SiAq2qr0lI9Se4ZbyVbBGVRckLGqeXx1t6z1yAvfUUGc/UXiz6EtZ8kPrVIx4RfRpur+V0pLjHtw9VEA6ocjm9tGirsYcR+HDPiT+ebJn4YxcLjqQ3rMNGpIOon9oNErpdtLJT88Piif0+Ix5Zgt8x7OCCr4dB9vfDIJU+JwkdaXaIJmxNqrXL23q3uZrdL8n8GurzYqb+OGj+kpVa9htxrJ9IPPhV1+IzXLGtMsm91uZgV29BnhWKS2I7IRnvP48izPPUaYmZNKNaXEl7PLfukJB/3jeBaHb3UR36p1y9tlj82FuiCsNZ82OgLMBMeQ== | ||
PublicExponent: AQAB | ||
PrivateExponent: gVUVUmIlWH8Rn0ELmLKL2LoohRpvwBHgELMFjqtnHmE9XD9oZxhxwbZttfvdWZv6AHilb0IJSeMUkCgZOROwA3OiTyKVaYaZdn0Legn3XO2YBVBXjYoup6wkgCq4T/O5jaYIhCL7Mqi13s2nhpQoopJrRm+uBiKneQv+H/T6mk4wwJH9mX9OrDgtHWXlSm1Pn+axmdo4QOmitLoSHYGb0bHC8QuDp3jQqrjdyKHaZjQalhxjI3J/YU9Gcqg/7zV3G+/z9/57SIXiT3pYhrKyHtXVPAnEkY7Mlv4mChBB2kXVz+sjQBzRWxLwEupzOt/MTciy2zU3BmTaCqmzRx9g4Q== | ||
Prime1: 7pM3ICtPxu2TyUo0BBFP/MC1x/4dtthGNb9u/NvtaDz7hebbVpivma6sUYy2Cr/qU6LKtla8S4n/2ZFDDBZ/m7dOYH7S4pTamR1sg31utYaaXXz/NaOqvflLhL9zHIG0cVFXBJbBk1TxQCPnPMBxxIAO71YqlxpkJDpmc7dSaQ0= | ||
Prime2: yg0QNP0BiBjU+K3+2OD3TILotg3UKuh9vPNVP4yAThBb8Tj42T+v5Lp0ngAbjorNTcwwFHcWaNkW+xIERt7Qszpc168aidTkBtzKHq8auPUXjYLTqmPOMTjkuKQpJA8mkSFrK0EXOD+PzEbTXT9hf2tJmwQYqpnzfksDTgIOfh0= | ||
Exponent1: FZRrYBWK2cuTmpmDqvqF6a7kwnpR5cAaWbI/L9AU4WDiv3HqVSLqf1Q1cgrwTHifkYEgJO4jihGpetyQ2/8M++DQzhmqqaQdQcxPjHVEFldejyZHT2rGfviVxCQtHV7+G2HoJRod2F3OlKaqu+wMXmHW9/8rSw+wDzbZHY5vfeE= | ||
Exponent2: sw4MlMi5+L/4zEB1ngEPZvCEBgIPSc8qzq3dmCmM8qEwuX7BmNUFrW9HNVXnFdUPx6fx29EFPPlVkj4PKDcBQDOyXzlADXFqemJjg/mtdsdMjg2oQlGcQqammrJv+xKqHOc+r+BJEYHSjzcczIAEiQStAAELUvSHgh472X+dFEk= | ||
Coefficient: s0ZyxTFjS5t/G95NNUd4eUpX6rfw4NIl93O6ZfEB0VLoqw3B0XOShE4jR5bDx5kQv0y023jVct69rrrw9qsJP7dYor5JnjJq7Wx6RGYEYXs0crD9JLI8Jk+teVGkxA0iFbhEp/cScS48D+cWHW4wC7aTIOyaciYVZTnaarZuLhA= | ||
Created: 20220429130726 | ||
Publish: 20220429130726 | ||
Activate: 20220429130726 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
/* eslint-env mocha */ | ||
/* eslint prefer-arrow-callback: "off" */ | ||
|
||
'use strict'; | ||
|
||
const assert = require('bsert'); | ||
const path = require('path'); | ||
const Ownership = require('../lib/ownership'); | ||
const dnssec = require('../lib/dnssec'); | ||
const { | ||
types, | ||
Message, | ||
Record | ||
} = require('../lib/wire'); | ||
|
||
describe('Ownership Proof Key Upgrade', function () { | ||
// Create a fake stub resolver with our own root zone and one TLD. | ||
// Root zone is signed with ED25519 but weakkeytld is signed with RSASHA1. | ||
// The RRSIGs in these zones expire on Dec. 31 2080. So, you know. Heads up. | ||
class Stub { | ||
lookup (name, type) { | ||
const msg = new Message(); | ||
switch (name) { | ||
case 'weakkeytld.': | ||
switch (type) { | ||
case types.DS: | ||
msg.answer.push(Record.fromString( | ||
'weakkeytld. DS 3810 5 2 ' + | ||
'BE06B4A3C4E50914DDE8670D68EFE6E04' + | ||
'24941B3F9BD364210BDFAFD6AF23526' | ||
)); | ||
msg.answer.push(Record.fromString( | ||
'weakkeytld. 300 RRSIG DS 15 1 300 ' + | ||
'20801231000000 20220429134556 28750 . ' + | ||
'3LfCEc+Yyx9OjWONSx41iphYjqJSKN2mUXM2' + | ||
'A1MCLBqx93b+T7FGPJUxAmumxR6T5v/VZ37+' + | ||
'9d6LwTfOxgVfBg==' | ||
|
||
)); | ||
break; | ||
case types.TXT: | ||
msg.answer.push(Record.fromString( | ||
'weakkeytld. 300 TXT "hns-claim"' | ||
)); | ||
msg.answer.push(Record.fromString( | ||
'weakkeytld. 300 RRSIG TXT 5 1 300 ' + | ||
'20801231000000 20220429134807 3810 weakkeytld. ' + | ||
'K9VKxanJnr8jI9zGtStG37TIIBmks9w2LH2Y' + | ||
'jD5SKkKiBPB4Orc9sLLlEm1FL5eOl8er4xYK' + | ||
'wue68e5xJn3njkuwmEx2SpalDKCubQrxuIQJ' + | ||
'dEHiAr2+bl++vvVn4V30s6rcU5rK4XmnjzUt' + | ||
'z12dB+++EMW3K17tbbhzVgFB5T/iBeCgrsjw' + | ||
'M+iKc0DYH8xo/yE4y/y64SjzfNy9Q2zxA1Zm' + | ||
'wkgqxVTKxw1W1GwuQiUkmy8xTTpSwFBpadOJ' + | ||
'GHmjUTiopRMr46aqO1p9VB/vO5V1hNzVa9Zp' + | ||
'G7aoAOANhqYSQ7um2//oCPr4xRQHgaCf0wdz' + | ||
'yczVBX4oLOLk4uvUeg==' | ||
)); | ||
break; | ||
case types.DNSKEY: | ||
msg.answer.push(Record.fromString( | ||
'weakkeytld. 300 DNSKEY 256 3 5 ' + | ||
'AwEAAbxMVhPD8UYltM6GnnP74rf0ogKtqq9J' + | ||
'SPUnuGW8lWwRlUXJCxqnl8dbes9cgL31FBnP' + | ||
'1F4s+hLWfJD61SMeEX0abq/ldKS4x7cPVRAO' + | ||
'qHI5vbRoq7GHEfhwz4k/nmyZ+GMXC46kN6zD' + | ||
'RqSDqJ/aDRK6XbSyU/PD4on9PiMeWYLfMezg' + | ||
'gq+HQfb3wyCVPicJHWl2iCZsTaq1y9t6t7ma' + | ||
'3S/J/Brq82Km/jho/pKVWvYbcayfSDz4Vdfi' + | ||
'M1yxrTLJvdbmYFdvQZ4ViktiOyEZ7z+PIszz' + | ||
'1GmJmTSjWlxJezy37pCQf943gWh291Ed+qdc' + | ||
'vbZY/NhbogrDWfNjoCzATHk=' | ||
)); | ||
msg.answer.push(Record.fromString( | ||
'weakkeytld. 300 RRSIG DNSKEY 5 1 300 ' + | ||
'20801231000000 20220429134807 3810 weakkeytld. ' + | ||
'kiTnUHoXHB8MC42iJImgIi2U4+xrUILV7sKw' + | ||
'f3KA6NK4AaMgReRqMCo67IOt/vwu6g47qeaq' + | ||
'/47AYXGA4vXYXdv49EOeUQvwB7AD/tAMHSy0' + | ||
'+TwyJOHgja0Fl0kgkGoIhkWB8MSWHT86E0qN' + | ||
'OnoO9rFFgHx91hgxZM5Nll/pEr/kQuDTJK/o' + | ||
'ixjluxGkkN+AgIN3spZTWx4fN2hOvWriLv8+' + | ||
'CwFGdqZuOa+lSpXh+EcnVBOJhagCrrxpsyN8' + | ||
'8NI+E5nsxyNS8rWRWnE7gX3GQi+xBFbe2RzJ' + | ||
'pQW+D+MDS8ofo9QWTIV7ho6xSjzfq8uKi/nt' + | ||
'2PBkdBNo35e1c30YLw==' | ||
)); | ||
break; | ||
} | ||
break; | ||
|
||
case '.': | ||
switch (type) { | ||
case types.DNSKEY: | ||
msg.answer.push(Record.fromString( | ||
'. 300 DNSKEY 257 3 15 '+ | ||
'2cUGwCbFjpVkvUS1ZLH0sA+K4K4nExUtMjr7iCvoTWQ=' | ||
)); | ||
msg.answer.push(Record.fromString( | ||
'. 300 RRSIG DNSKEY 15 0 300 ' + | ||
'20801231000000 20220429134556 28750 . ' + | ||
'KeXA54XobZC8MV3OTgtUdTNvd5nt40lFDech' + | ||
'LUt+ngF5cvZV5CnSoFWgMc4/LEKRVVIhAKzc' + | ||
'v6PqrzgJCuTTDA==' | ||
)); | ||
break; | ||
} | ||
} | ||
return msg; | ||
} | ||
}; | ||
|
||
const ownership = new Ownership(); | ||
|
||
// Trust anchor for our fake local root zone | ||
ownership.anchors = [Record.fromString( | ||
'. DS 28750 15 2 '+ | ||
'3B194170CF9EDF967B50CA146386F08E573E52919983BAF03B8E66E2A43D7900' | ||
)]; | ||
|
||
// Hack instanceof assertion in ownership._prove() | ||
ownership.Resolver = Stub; | ||
|
||
it('should fail by default to generate RSASHA1 proof', async () => { | ||
// They don't even count as actual RRSIGs | ||
await assert.rejects( | ||
ownership._prove(new Stub(), 'weakkeytld.', false), | ||
{message: 'No RRSIG(TXT) records for weakkeytld.'} | ||
); | ||
|
||
// Sanity check | ||
const res = new Stub().lookup('weakkeytld.', types.TXT); | ||
assert(res.answer[1].type === types.RRSIG); | ||
assert(ownership.isSHA1(res.answer[1].data.algorithm)); | ||
}); | ||
|
||
it('should generate RSASHA1 proof with secure=false', async () => { | ||
try { | ||
ownership.secure = false; | ||
const proof = await ownership._prove(new Stub(), 'weakkeytld.', false); | ||
assert(proof.zones[1].claim[1].type === types.RRSIG); | ||
assert(ownership.isSHA1(proof.zones[1].claim[1].data.algorithm)); | ||
} finally { | ||
ownership.secure = true; // default | ||
} | ||
}); | ||
|
||
it('should upgrade weak key algorithm', async () => { | ||
let proof, target; | ||
try { | ||
ownership.secure = false; // need secure=false just to get proof template | ||
proof = await ownership._prove(new Stub(), 'weakkeytld.', true); | ||
target = proof.zones[1]; | ||
const key = target.keys[0]; | ||
const txtRR = proof.zones[1].claim[0]; | ||
|
||
assert(key.type === types.DNSKEY); | ||
assert(txtRR.type === types.TXT); | ||
|
||
// Kweakkeytld.+005+03810.private | ||
const priv = await dnssec.readPrivateAsync( | ||
path.join(__dirname, 'data'), | ||
key | ||
); | ||
|
||
// Here's the sneaky magic: create a duplicate key with better algorithm. | ||
const key256 = dnssec.upgradeDNSKEY(key); | ||
|
||
// Sign DNSKEY RRset now including both old and new keys. | ||
const keySig = dnssec.sign(key256, priv, [key256, key], 24 * 60 * 60); | ||
target.keys[0] = key; | ||
target.keys[1] = key256; | ||
target.keys[2] = keySig; | ||
|
||
// Now sign the claim TXT with the new key | ||
const txtSig = dnssec.sign(key256, priv, [txtRR], 24 * 60 * 60); | ||
target.claim[1] = txtSig; | ||
} finally { | ||
ownership.secure = true; // default, and required by HNS consenus rules | ||
} | ||
|
||
assert(ownership.isSane(proof)); | ||
assert(ownership.verifySignatures(proof)); | ||
|
||
// Sanity check | ||
assert(target.claim[1].type === types.RRSIG); | ||
assert(!ownership.isSHA1(target.claim[1].data.algorithm)); | ||
}); | ||
}); |