TLS (continued) and DNS
CS 161 Spring 2022 - Lecture 19
Computer Science 161
Nicholas Weaver
Announcements
2
Computer Science 161
Nicholas Weaver
TLS in Practice
Textbook Chapter 31.3
3
Computer Science 161
Nicholas Weaver
TLS: Efficiency
4
Computer Science 161
Nicholas Weaver
TLS Provides End-to-End Security
5
Computer Science 161
Nicholas Weaver
TLS Does Not Provide Anonymity
6
Computer Science 161
Nicholas Weaver
TLS Does Not Provide Availability
7
Computer Science 161
Nicholas Weaver
TLS for Applications
8
Computer Science 161
Nicholas Weaver
SSL Stripping Attacks
9
User
Attacker
Server
HTTP
HTTPS
Computer Science 161
Nicholas Weaver
TLS in Browsers
10
This website uses HTTP: no lock icon
This website uses HTTPS: lock icon
Computer Science 161
Nicholas Weaver
TLS in Browsers
11
Computer Science 161
Nicholas Weaver
TLS in Browsers
12
This website uses HTTP: insecure icon
This website uses HTTPS: lock icon
Computer Science 161
Nicholas Weaver
TLS Attack: PRNG Sabotage
13
Computer Science 161
Nicholas Weaver
TLS Trust Issues: Certificate Authorities
14
But we can delegate…
Computer Science 161
Nicholas Weaver
Recall: Certificates in TLS
15
Computer Science 161
Nicholas Weaver
Issues: Unknown Certificate Authority
16
Computer Science 161
Nicholas Weaver
Verifying Certificates
17
Computer Science 161
Nicholas Weaver
Verifying Certificates
18
Computer Science 161
Nicholas Weaver
Issues: Revocation
19
Computer Science 161
Nicholas Weaver
Issues: Trust Anchors
20
Computer Science 161
Nicholas Weaver
Issues: Trust Anchors
Takeaway: Trust certificate authorities can be compromised by hackers
21
| |
Solo Iranian hacker takes credit for Comodo certificate attack | |
Gregg Keizer | March 27, 2011 |
Security researchers split on whether 'ComodoHacker' is the real deal A solo Iranian hacker on Saturday claimed responsibility for stealing multiple SSL certificates belonging to some of the Web's biggest sites, including Google, Microsoft, Skype and Yahoo. Early reaction from security experts was mixed, with some believing the hacker's claim, while others were dubious. |
Computer Science 161
Nicholas Weaver
Issues: Trust Anchors
Takeaway: Trust certificate authorities can be compromised by hackers
22
| |
Fraudulent Google certificate points to Internet attack | |
Elinor Mills | August 29, 2011 |
Is Iran behind a fraudulent Google.com digital certificate? The situation is similar to one that happened in March in which spoofed certificates were traced back to Iran. A Dutch company appears to have issued a digital certificate for Google.com to someone other than Google, who may be using it to try to re-direct traffic of users based in Iran. Yesterday, someone reported on a Google support site that when attempting to log in to Gmail the browser issued a warning for the digital certificate used as proof that the site is legitimate, according to this thread on a Google support forum site. |
Computer Science 161
Nicholas Weaver
Issues: Trust Anchors
Takeaway: Trust certificate authorities can be compromised by hackers
23
| |
Final Report on DigiNotar Hack Shows Total Compromise of CA Servers | |
Dennis Fisher | October 31, 2012 |
The attacker who penetrated the Dutch CA DigiNotar last year had complete control of all eight of the company’s certificate-issuing servers during the operation and he may also have issued some rogue certificates that have not yet been identified. |
Computer Science 161
Nicholas Weaver
Issues: Trust Anchors
Takeaway: Trust certificate authorities can be compromised by hackers
24
| |
Evidence Suggests DigiNotar, Who Issued Fraudulent�Google Certificate, Was Hacked Years Ago | |
Mike Masnick | August 30, 2011 |
The big news in the security world, obviously, is the fact that a fraudulent Google certificate made its way out into the wild, apparently targeting internet users in Iran. The Dutch company DigiNotar has put out a statement saying that it discovered a breach back on July 19th during a security audit, and that fraudulent certificates were generated for "several dozen" websites. The only one known to have gotten out into the wild is the Google one. |
Computer Science 161
Nicholas Weaver
Issues: Trust Anchors
25
Computer Science 161
Nicholas Weaver
Solving Trust Issues
26
Computer Science 161
Nicholas Weaver
Solving Trust Issues
27
Computer Science 161
Nicholas Weaver
Certificate Authority Example: Let’s Encrypt
28
Computer Science 161
Nicholas Weaver
Using Let’s Encrypt in Go
import "golang.org/x/crypto/acme/autocert" ��... � log.Fatal(http.Serve(autocert.NewListener("example.com"), handler))
29
Computer Science 161
Nicholas Weaver
TLS Today
30
Computer Science 161
Nicholas Weaver
TLS: Summary
31
Client
Server
ClientHello
ServerHello
Certificate
{ga mod p}K-1server
gb mod p
{M, MAC(IB, M)}CB
{M, MAC(IS, M)}CS
Or RSA exchange
Computer Science 161
Nicholas Weaver
TLS: Summary
32
Computer Science 161
Nicholas Weaver
DNS
33
Computer Science 161
Nicholas Weaver
Domain Names
34
Computer Science 161
Nicholas Weaver
DNS: Definition
35
74.125.25.99
www.google.com
DNS
Computer Science 161
Nicholas Weaver
DNS Name Servers
36
Computer Science 161
Nicholas Weaver
DNS Name Server Hierarchy
37
. (root)
.edu
.org
.com
google.com
piazza.com
cs161.org
mit.edu
berkeley.edu
Computer Science 161
Nicholas Weaver
DNS Name Server Hierarchy
38
Each box is a name server. The label represents which queries the name server is responsible for answering.
. (root)
.edu
.org
.com
google.com
piazza.com
cs161.org
mit.edu
berkeley.edu
For example, this name server is responsible for .edu queries like eecs.berkeley.edu, but not a query like mail.google.com.
Computer Science 161
Nicholas Weaver
Steps of a DNS Lookup
39
. (root)
.edu
.org
cs161.org
mit.edu
berkeley.edu
You
Let's walk through a DNS query for the IP address of eecs.berkeley.edu.
Computer Science 161
Nicholas Weaver
Steps of a DNS Lookup
40
. (root)
.edu
.org
cs161.org
mit.edu
berkeley.edu
You
DNS queries always start with a request to the root name server, which is responsible for all requests.
1
“What is the IP address of eecs.berkeley.edu?”
Computer Science 161
Nicholas Weaver
Steps of a DNS Lookup
41
. (root)
.edu
.org
cs161.org
mit.edu
berkeley.edu
You
The root name server responds by directing you to the correct child name server (in this case, the .edu name server).
1
2
“I don’t know, but I have delegated authority to the .edu name server.”
Computer Science 161
Nicholas Weaver
Steps of a DNS Lookup
42
. (root)
.edu
.org
cs161.org
mit.edu
berkeley.edu
You
1
2
3
“What is the IP address of eecs.berkeley.edu?”
Computer Science 161
Nicholas Weaver
Steps of a DNS Lookup
43
. (root)
.edu
.org
cs161.org
mit.edu
berkeley.edu
You
3
4
“I don’t know. But I have delegated authority to the berkeley.edu name server.”
1
2
Computer Science 161
Nicholas Weaver
Steps of a DNS Lookup
44
. (root)
.edu
.org
cs161.org
mit.edu
berkeley.edu
You
“What is the IP address of eecs.berkeley.edu?”
3
4
1
2
5
Computer Science 161
Nicholas Weaver
Steps of a DNS Lookup
45
. (root)
.edu
.org
cs161.org
mit.edu
berkeley.edu
You
5
6
“The IP address of eecs.berkeley.edu is 23.185.0.1.”
3
4
1
2
Computer Science 161
Nicholas Weaver
Stub Resolvers and Recursive Resolvers
46
Computer Science 161
Nicholas Weaver
Steps of a DNS Lookup
47
. (root)
.edu
.org
cs161.org
mit.edu
berkeley.edu
Stub Resolver
The stub resolver sends the query to the recursive resolver.
1
Recursive Resolver
Computer Science 161
Nicholas Weaver
Steps of a DNS Lookup
48
. (root)
.edu
.org
cs161.org
mit.edu
berkeley.edu
Stub Resolver
The recursive resolver contacts all the name servers to answer the query, as we saw earlier.
Recursive Resolver
1
6
7
4
5
3
2
Computer Science 161
Nicholas Weaver
Steps of a DNS Lookup
49
. (root)
.edu
.org
cs161.org
mit.edu
berkeley.edu
Stub Resolver
The recursive resolver returns the final answer to the stub resolver.
Recursive Resolver
1
8
6
7
4
5
3
2
Computer Science 161
Nicholas Weaver
DNS Message Format
50
Computer Science 161
Nicholas Weaver
DNS Uses UDP
51
Computer Science 161
Nicholas Weaver
DNS Packet Format: UDP Header
52
Source Port | Destination Port |
Checksum | Length |
ID number | Flags |
Question count | Answer count |
Authority count | Additional count |
Question Records | |
Answer Records | |
Authority Records | |
Additional Records |
UDP Payload
UDP Header
Computer Science 161
Nicholas Weaver
DNS Packet Format: DNS Payload
53
Source Port | Destination Port |
Checksum | Length |
ID number | Flags |
Question count | Answer count |
Authority count | Additional count |
Question Records | |
Answer Records | |
Authority Records | |
Additional Records |
DNS Payload
UDP Header
DNS Header
Computer Science 161
Nicholas Weaver
DNS Packet Format: DNS Header
54
Source Port | Destination Port |
Checksum | Length |
ID number | Flags |
Question count | Answer count |
Authority count | Additional count |
Question Records | |
Answer Records | |
Authority Records | |
Additional Records |
DNS Payload
UDP Header
DNS Header
Computer Science 161
Nicholas Weaver
DNS Record Format
55
Computer Science 161
Nicholas Weaver
DNS Record Types
56
Computer Science 161
Nicholas Weaver
DNS Record Sections
57
Computer Science 161
Nicholas Weaver
DNS Record Sections
58
Computer Science 161
Nicholas Weaver
DNS Record Caching
59
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
60
You can try this at home! Use the dig utility in your terminal, and remember to set the +norecurse flag so you can traverse the name server hierarchy yourself.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
61
We are performing a DNS lookup for the IP address of eecs.berkeley.edu.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
62
DNS queries always start with a request to the root name server. The IP address of the root name server is usually hard-coded into recursive resolvers.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26114
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; AUTHORITY SECTION:
edu. 172800 IN NS a.edu-servers.net.
edu. 172800 IN NS b.edu-servers.net.
edu. 172800 IN NS c.edu-servers.net.
...
;; ADDITIONAL SECTION:
a.edu-servers.net. 172800 IN A 192.5.6.30
b.edu-servers.net. 172800 IN A 192.33.14.30
c.edu-servers.net. 172800 IN A 192.26.92.30
...
63
Here’s the DNS response from the root name server.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26114
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; AUTHORITY SECTION:
edu. 172800 IN NS a.edu-servers.net.
edu. 172800 IN NS b.edu-servers.net.
edu. 172800 IN NS c.edu-servers.net.
...
;; ADDITIONAL SECTION:
a.edu-servers.net. 172800 IN A 192.5.6.30
b.edu-servers.net. 172800 IN A 192.33.14.30
c.edu-servers.net. 172800 IN A 192.26.92.30
...
64
Here’s the DNS header.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26114
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; AUTHORITY SECTION:
edu. 172800 IN NS a.edu-servers.net.
edu. 172800 IN NS b.edu-servers.net.
edu. 172800 IN NS c.edu-servers.net.
...
;; ADDITIONAL SECTION:
a.edu-servers.net. 172800 IN A 192.5.6.30
b.edu-servers.net. 172800 IN A 192.33.14.30
c.edu-servers.net. 172800 IN A 192.26.92.30
...
65
Here’s the 16-bit ID number in the DNS header.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26114
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; AUTHORITY SECTION:
edu. 172800 IN NS a.edu-servers.net.
edu. 172800 IN NS b.edu-servers.net.
edu. 172800 IN NS c.edu-servers.net.
...
;; ADDITIONAL SECTION:
a.edu-servers.net. 172800 IN A 192.5.6.30
b.edu-servers.net. 172800 IN A 192.33.14.30
c.edu-servers.net. 172800 IN A 192.26.92.30
...
66
Here are the flags in the DNS header.
Here are the record counts in the DNS header.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26114
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; AUTHORITY SECTION:
edu. 172800 IN NS a.edu-servers.net.
edu. 172800 IN NS b.edu-servers.net.
edu. 172800 IN NS c.edu-servers.net.
...
;; ADDITIONAL SECTION:
a.edu-servers.net. 172800 IN A 192.5.6.30
b.edu-servers.net. 172800 IN A 192.33.14.30
c.edu-servers.net. 172800 IN A 192.26.92.30
...
67
Here’s the DNS payload. It’s a collection of resource records (one per line), sorted into four sections.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26114
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; AUTHORITY SECTION:
edu. 172800 IN NS a.edu-servers.net.
edu. 172800 IN NS b.edu-servers.net.
edu. 172800 IN NS c.edu-servers.net.
...
;; ADDITIONAL SECTION:
a.edu-servers.net. 172800 IN A 192.5.6.30
b.edu-servers.net. 172800 IN A 192.33.14.30
c.edu-servers.net. 172800 IN A 192.26.92.30
...
68
Here’s the question section. The name is eecs.berkeley.edu, the type is A, and the value is blank. It shows that we are looking for the IP address of eecs.berkeley.edu.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26114
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; AUTHORITY SECTION:
edu. 172800 IN NS a.edu-servers.net.
edu. 172800 IN NS b.edu-servers.net.
edu. 172800 IN NS c.edu-servers.net.
...
;; ADDITIONAL SECTION:
a.edu-servers.net. 172800 IN A 192.5.6.30
b.edu-servers.net. 172800 IN A 192.33.14.30
c.edu-servers.net. 172800 IN A 192.26.92.30
...
69
The answer section is blank, because the root name server did not return the answer we’re looking for.
We can confirm this by checking the header, which says there are 0 records in the answer section.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26114
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; AUTHORITY SECTION:
edu. 172800 IN NS a.edu-servers.net.
edu. 172800 IN NS b.edu-servers.net.
edu. 172800 IN NS c.edu-servers.net.
...
;; ADDITIONAL SECTION:
a.edu-servers.net. 172800 IN A 192.5.6.30
b.edu-servers.net. 172800 IN A 192.33.14.30
c.edu-servers.net. 172800 IN A 192.26.92.30
...
70
The authority and additional sections tell the resolver where to look next.
Note that there are multiple .edu name servers for redundancy.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26114
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; AUTHORITY SECTION:
edu. 172800 IN NS a.edu-servers.net.
edu. 172800 IN NS b.edu-servers.net.
edu. 172800 IN NS c.edu-servers.net.
...
;; ADDITIONAL SECTION:
a.edu-servers.net. 172800 IN A 192.5.6.30
b.edu-servers.net. 172800 IN A 192.33.14.30
c.edu-servers.net. 172800 IN A 192.26.92.30
...
71
For redundancy, there are usually several name servers for each zone. Any of them will usually work. Let’s pick the first one.
This NS record says that a.edu-servers.net is a .edu name server.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @198.41.0.4
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26114
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; AUTHORITY SECTION:
edu. 172800 IN NS a.edu-servers.net.
edu. 172800 IN NS b.edu-servers.net.
edu. 172800 IN NS c.edu-servers.net.
...
;; ADDITIONAL SECTION:
a.edu-servers.net. 172800 IN A 192.5.6.30
b.edu-servers.net. 172800 IN A 192.33.14.30
c.edu-servers.net. 172800 IN A 192.26.92.30
...
72
This A record helpfully tells us the IP address of the next name server we mean to contact.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @192.5.6.30
73
Next, we query the .edu name server. We know the IP address of the .edu name server because the root name server gave the information to us.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @192.5.6.30
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36257
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 3, ADDITIONAL: 5
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; AUTHORITY SECTION:
berkeley.edu. 172800 IN NS adns1.berkeley.edu.
berkeley.edu. 172800 IN NS adns2.berkeley.edu.
berkeley.edu. 172800 IN NS adns3.berkeley.edu.
;; ADDITIONAL SECTION:
adns1.berkeley.edu. 172800 IN A 128.32.136.3
adns2.berkeley.edu. 172800 IN A 128.32.136.14
adns3.berkeley.edu. 172800 IN A 192.107.102.142
...
74
The answer section is blank again. The authority and additional section tell us to query a berkeley.edu name server, and provide us with the IP address of the next name server.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @128.32.136.3
75
Next, we query the berkeley.edu name server for the IP address of eecs.berkeley.edu. We know the IP address of the berkeley.edu name server because the root name server gave the information to us.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @128.32.136.3
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52788
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; ANSWER SECTION:
eecs.berkeley.edu. 86400 IN A 23.185.0.1
76
The answer section has one A type record. It tells us that the IP address of eecs.berkeley.edu is 23.185.0.1.
Computer Science 161
Nicholas Weaver
DNS Lookup Walkthrough
$ dig +norecurse eecs.berkeley.edu @128.32.136.3
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52788
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; ANSWER SECTION:
eecs.berkeley.edu. 86400 IN A 23.185.0.1
77
Here’s the time-to-live (TTL) field in the record. It tells us that we can cache this answer for 86,400 seconds (24 hours).
Computer Science 161
Nicholas Weaver
DNS Security
78
Computer Science 161
Nicholas Weaver
Cache Poisoning Attacks
79
Computer Science 161
Nicholas Weaver
Security Risk: Malicious Name Servers
$ dig +norecurse eecs.berkeley.edu @128.32.136.3
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52788
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;eecs.berkeley.edu. IN A
;; ANSWER SECTION:
eecs.berkeley.edu. 86400 IN A 23.185.0.1
;; ADDITIONAL SECTION:
www.google.com. 172800 IN A 6.6.6.6
80
We made a query to a malicious berkeley.edu name server...
...and it returned a malicious record for www.google.com!
Computer Science 161
Nicholas Weaver
Defense: Bailiwick Checking
81
Computer Science 161
Nicholas Weaver
Security Risk: Man-in-the-middle (MITM) Attackers
82
;; ANSWER SECTION:
eecs.berkeley.edu. 86400 IN A 23.185.0.1 6.6.6.6
Computer Science 161
Nicholas Weaver
Security Risk: On-Path Attackers
83
Recursive Resolver
berkeley.edu name server
Attacker
Computer Science 161
Nicholas Weaver