]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - docs/specifications/uri.rst
fix warnings from rst2html
[tahoe-lafs/tahoe-lafs.git] / docs / specifications / uri.rst
1 .. -*- coding: utf-8-with-signature -*-
2
3 ==========
4 Tahoe URIs
5 ==========
6
7 1.  `File URIs`_
8
9     1. `CHK URIs`_
10     2. `LIT URIs`_
11     3. `Mutable File URIs`_
12
13 2.  `Directory URIs`_
14 3.  `Internal Usage of URIs`_
15
16 Each file and directory in a Tahoe filesystem is described by a "URI". There
17 are different kinds of URIs for different kinds of objects, and there are
18 different kinds of URIs to provide different kinds of access to those
19 objects. Each URI is a string representation of a "capability" or "cap", and
20 there are read-caps, write-caps, verify-caps, and others.
21
22 Each URI provides both ``location`` and ``identification`` properties.
23 ``location`` means that holding the URI is sufficient to locate the data it
24 represents (this means it contains a storage index or a lookup key, whatever
25 is necessary to find the place or places where the data is being kept).
26 ``identification`` means that the URI also serves to validate the data: an
27 attacker who wants to trick you into into using the wrong data will be
28 limited in their abilities by the identification properties of the URI.
29
30 Some URIs are subsets of others. In particular, if you know a URI which
31 allows you to modify some object, you can produce a weaker read-only URI and
32 give it to someone else, and they will be able to read that object but not
33 modify it. Directories, for example, have a read-cap which is derived from
34 the write-cap: anyone with read/write access to the directory can produce a
35 limited URI that grants read-only access, but not the other way around.
36
37 src/allmydata/uri.py is the main place where URIs are processed. It is
38 the authoritative definition point for all the the URI types described
39 herein.
40
41 File URIs
42 =========
43
44 The lowest layer of the Tahoe architecture (the "grid") is reponsible for
45 mapping URIs to data. This is basically a distributed hash table, in which
46 the URI is the key, and some sequence of bytes is the value.
47
48 There are two kinds of entries in this table: immutable and mutable. For
49 immutable entries, the URI represents a fixed chunk of data. The URI itself
50 is derived from the data when it is uploaded into the grid, and can be used
51 to locate and download that data from the grid at some time in the future.
52
53 For mutable entries, the URI identifies a "slot" or "container", which can be
54 filled with different pieces of data at different times.
55
56 It is important to note that the "files" described by these URIs are just a
57 bunch of bytes, and that **no** filenames or other metadata is retained at
58 this layer. The vdrive layer (which sits above the grid layer) is entirely
59 responsible for directories and filenames and the like.
60
61 CHK URIs
62 --------
63
64 CHK (Content Hash Keyed) files are immutable sequences of bytes. They are
65 uploaded in a distributed fashion using a "storage index" (for the "location"
66 property), and encrypted using a "read key". A secure hash of the data is
67 computed to help validate the data afterwards (providing the "identification"
68 property). All of these pieces, plus information about the file's size and
69 the number of shares into which it has been distributed, are put into the
70 "CHK" uri. The storage index is derived by hashing the read key (using a
71 tagged SHA-256d hash, then truncated to 128 bits), so it does not need to be
72 physically present in the URI.
73
74 The current format for CHK URIs is the concatenation of the following
75 strings::
76
77  URI:CHK:(key):(hash):(needed-shares):(total-shares):(size)
78
79 Where (key) is the base32 encoding of the 16-byte AES read key, (hash) is the
80 base32 encoding of the SHA-256 hash of the URI Extension Block,
81 (needed-shares) is an ascii decimal representation of the number of shares
82 required to reconstruct this file, (total-shares) is the same representation
83 of the total number of shares created, and (size) is an ascii decimal
84 representation of the size of the data represented by this URI. All base32
85 encodings are expressed in lower-case, with the trailing '=' signs removed.
86
87 For example, the following is a CHK URI, generated from a previous version of
88 the contents of architecture.rst_::
89
90  URI:CHK:ihrbeov7lbvoduupd4qblysj7a:bg5agsdt62jb34hxvxmdsbza6do64f4fg5anxxod2buttbo6udzq:3:10:28733
91
92 Historical note: The name "CHK" is somewhat inaccurate and continues to be
93 used for historical reasons. "Content Hash Key" means that the encryption key
94 is derived by hashing the contents, which gives the useful property that
95 encoding the same file twice will result in the same URI. However, this is an
96 optional step: by passing a different flag to the appropriate API call, Tahoe
97 will generate a random encryption key instead of hashing the file: this gives
98 the useful property that the URI or storage index does not reveal anything
99 about the file's contents (except filesize), which improves privacy. The
100 URI:CHK: prefix really indicates that an immutable file is in use, without
101 saying anything about how the key was derived.
102
103 .. _architecture.rst: ../architecture.rst
104
105
106 LIT URIs
107 --------
108
109 LITeral files are also an immutable sequence of bytes, but they are so short
110 that the data is stored inside the URI itself. These are used for files of 55
111 bytes or shorter, which is the point at which the LIT URI is the same length
112 as a CHK URI would be.
113
114 LIT URIs do not require an upload or download phase, as their data is stored
115 directly in the URI.
116
117 The format of a LIT URI is simply a fixed prefix concatenated with the base32
118 encoding of the file's data::
119
120  URI:LIT:bjuw4y3movsgkidbnrwg26lemf2gcl3xmvrc6kropbuhi3lmbi
121
122 The LIT URI for an empty file is "URI:LIT:", and the LIT URI for a 5-byte
123 file that contains the string "hello" is "URI:LIT:nbswy3dp".
124
125 Mutable File URIs
126 -----------------
127
128 The other kind of DHT entry is the "mutable slot", in which the URI names a
129 container to which data can be placed and retrieved without changing the
130 identity of the container.
131
132 These slots have write-caps (which allow read/write access), read-caps (which
133 only allow read-access), and verify-caps (which allow a file checker/repairer
134 to confirm that the contents exist, but does not let it decrypt the
135 contents).
136
137 Mutable slots use public key technology to provide data integrity, and put a
138 hash of the public key in the URI. As a result, the data validation is
139 limited to confirming that the data retrieved matches *some* data that was
140 uploaded in the past, but not _which_ version of that data.
141
142 The format of the write-cap for mutable files is::
143
144  URI:SSK:(writekey):(fingerprint)
145
146 Where (writekey) is the base32 encoding of the 16-byte AES encryption key
147 that is used to encrypt the RSA private key, and (fingerprint) is the base32
148 encoded 32-byte SHA-256 hash of the RSA public key. For more details about
149 the way these keys are used, please see mutable.rst_.
150
151 The format for mutable read-caps is::
152
153  URI:SSK-RO:(readkey):(fingerprint)
154
155 The read-cap is just like the write-cap except it contains the other AES
156 encryption key: the one used for encrypting the mutable file's contents. This
157 second key is derived by hashing the writekey, which allows the holder of a
158 write-cap to produce a read-cap, but not the other way around. The
159 fingerprint is the same in both caps.
160
161 Historical note: the "SSK" prefix is a perhaps-inaccurate reference to
162 "Sub-Space Keys" from the Freenet project, which uses a vaguely similar
163 structure to provide mutable file access.
164
165 .. _mutable.rst: mutable.rst
166
167
168 Directory URIs
169 ==============
170
171 The grid layer provides a mapping from URI to data. To turn this into a graph
172 of directories and files, the "vdrive" layer (which sits on top of the grid
173 layer) needs to keep track of "directory nodes", or "dirnodes" for short.
174 dirnodes.rst_ describes how these work.
175
176 Dirnodes are contained inside mutable files, and are thus simply a particular
177 way to interpret the contents of these files. As a result, a directory
178 write-cap looks a lot like a mutable-file write-cap::
179
180  URI:DIR2:(writekey):(fingerprint)
181
182 Likewise directory read-caps (which provide read-only access to the
183 directory) look much like mutable-file read-caps::
184
185  URI:DIR2-RO:(readkey):(fingerprint)
186
187 Historical note: the "DIR2" prefix is used because the non-distributed
188 dirnodes in earlier Tahoe releases had already claimed the "DIR" prefix.
189
190 .. _dirnodes.rst: dirnodes.rst
191
192
193 Internal Usage of URIs
194 ======================
195
196 The classes in source:src/allmydata/uri.py are used to pack and unpack these
197 various kinds of URIs. Three Interfaces are defined (IURI, IFileURI, and
198 IDirnodeURI) which are implemented by these classes, and string-to-URI-class
199 conversion routines have been registered as adapters, so that code which
200 wants to extract e.g. the size of a CHK or LIT uri can do::
201
202  print IFileURI(uri).get_size()
203
204 If the URI does not represent a CHK or LIT uri (for example, if it was for a
205 directory instead), the adaptation will fail, raising a TypeError inside the
206 IFileURI() call.
207
208 Several utility methods are provided on these objects. The most important is
209 ``to_string()``, which returns the string form of the URI. Therefore
210 ``IURI(uri).to_string == uri`` is true for any valid URI. See the IURI class
211 in source:src/allmydata/interfaces.py for more details.
212