Skip to content

Commit

Permalink
Dnssec oracle (ensdomains#10)
Browse files Browse the repository at this point in the history
* Copied over code from dnssec-oracle

* WIP

* Fix failing test

* Add dnsregistrar

* Add root

* Upgrade root and dnsregistrar

* Expose DNSSEC related libraries

* Add SuffixList

* v0.0.4
  • Loading branch information
makoto authored Jun 1, 2021
1 parent 4a21fc0 commit 16928d4
Show file tree
Hide file tree
Showing 47 changed files with 4,441 additions and 331 deletions.
303 changes: 0 additions & 303 deletions contracts/buffer/Buffer.sol

This file was deleted.

89 changes: 89 additions & 0 deletions contracts/dnsregistrar/DNSClaimChecker.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
pragma solidity ^0.8.4;

import "../dnssec-oracle/DNSSEC.sol";
import "../dnssec-oracle/BytesUtils.sol";
import "../dnssec-oracle/RRUtils.sol";
import "@ensdomains/buffer/contracts/Buffer.sol";

library DNSClaimChecker {

using BytesUtils for bytes;
using RRUtils for *;
using Buffer for Buffer.buffer;

uint16 constant CLASS_INET = 1;
uint16 constant TYPE_TXT = 16;

function getOwnerAddress(DNSSEC oracle, bytes memory name, bytes memory proof)
internal
view
returns (address, bool)
{
// Add "_ens." to the front of the name.
Buffer.buffer memory buf;
buf.init(name.length + 5);
buf.append("\x04_ens");
buf.append(name);
bytes20 hash;
uint64 inserted;
// Check the provided TXT record has been validated by the oracle
(, inserted, hash) = oracle.rrdata(TYPE_TXT, buf.buf);
if (hash == bytes20(0) && proof.length == 0) return (address(0x0), false);

require(hash == bytes20(keccak256(proof)));

for (RRUtils.RRIterator memory iter = proof.iterateRRs(0); !iter.done(); iter.next()) {
require(inserted + iter.ttl >= block.timestamp, "DNS record is stale; refresh or delete it before proceeding.");

bool found;
address addr;
(addr, found) = parseRR(proof, iter.rdataOffset);
if (found) {
return (addr, true);
}
}

return (address(0x0), false);
}

function parseRR(bytes memory rdata, uint idx) internal pure returns (address, bool) {
while (idx < rdata.length) {
uint len = rdata.readUint8(idx); idx += 1;

bool found;
address addr;
(addr, found) = parseString(rdata, idx, len);

if (found) return (addr, true);
idx += len;
}

return (address(0x0), false);
}

function parseString(bytes memory str, uint idx, uint len) internal pure returns (address, bool) {
// TODO: More robust parsing that handles whitespace and multiple key/value pairs
if (str.readUint32(idx) != 0x613d3078) return (address(0x0), false); // 0x613d3078 == 'a=0x'
if (len < 44) return (address(0x0), false);
return hexToAddress(str, idx + 4);
}

function hexToAddress(bytes memory str, uint idx) internal pure returns (address, bool) {
if (str.length - idx < 40) return (address(0x0), false);
uint ret = 0;
for (uint i = idx; i < idx + 40; i++) {
ret <<= 4;
uint x = str.readUint8(i);
if (x >= 48 && x < 58) {
ret |= x - 48;
} else if (x >= 65 && x < 71) {
ret |= x - 55;
} else if (x >= 97 && x < 103) {
ret |= x - 87;
} else {
return (address(0x0), false);
}
}
return (address(uint160(ret)), true);
}
}
Loading

0 comments on commit 16928d4

Please sign in to comment.