Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
daniel.eades
arti
Commits
c10de0c3
Commit
c10de0c3
authored
May 10, 2021
by
Nick Mathewson
👁
Browse files
Add builders for authority and fallback objects.
parent
c72193bd
Changes
3
Hide whitespace changes
Inline
Side-by-side
tor-dirmgr/src/authority.rs
View file @
c10de0c3
...
...
@@ -3,6 +3,7 @@
//! From a client's point of view, an authority's role is to to sign the
//! consensus directory.
use
crate
::{
Error
,
Result
};
use
serde
::
Deserialize
;
use
tor_llcrypto
::
pk
::
rsa
::
RsaIdentity
;
use
tor_netdoc
::
doc
::
authcert
::{
AuthCert
,
AuthCertKeyIds
};
...
...
@@ -23,11 +24,18 @@ pub struct Authority {
}
impl
Authority
{
/// Construct information about a new authority.
pub
fn
new
(
name
:
String
,
v3ident
:
RsaIdentity
)
->
Self
{
Authority
{
name
,
v3ident
}
/// Return a new builder for constructing an [`Authority`].
///
/// You only need this if you're using a non-default Tor network
/// with its own set of directory authorities.
pub
fn
builder
()
->
AuthorityBuilder
{
AuthorityBuilder
::
new
()
}
/// Return the v3 identity key of this certificate.
///
/// This is the identity of the >=2048-bit RSA key that the
/// authority uses to sign documents; it is distinct from its
/// identity keys that it uses when operating as a relay.
pub
fn
v3ident
(
&
self
)
->
&
RsaIdentity
{
&
self
.v3ident
}
...
...
@@ -46,11 +54,14 @@ impl Authority {
pub
(
crate
)
fn
default_authorities
()
->
Vec
<
Authority
>
{
/// Build an authority; panic if input is bad.
fn
auth
(
name
:
&
str
,
key
:
&
str
)
->
Authority
{
let
name
=
name
.to_string
();
let
v3ident
=
hex
::
decode
(
key
)
.expect
(
"Built-in authority identity had bad hex!?"
);
let
v3ident
=
RsaIdentity
::
from_bytes
(
&
v3ident
)
.expect
(
"Built-in authority identity had wrong length!?"
);
Authority
{
name
,
v3ident
}
AuthorityBuilder
::
new
()
.name
(
name
)
.v3ident
(
v3ident
)
.build
()
.expect
(
"unable to construct built-in authority!?"
)
}
// (List generated August 2020.)
...
...
@@ -67,6 +78,48 @@ pub(crate) fn default_authorities() -> Vec<Authority> {
]
}
/// A Builder object for constructing an [`Authority`] entry.
#[derive(Debug,
Clone,
Default)]
pub
struct
AuthorityBuilder
{
/// See [`Authority::name`]
name
:
Option
<
String
>
,
/// See [`Authority::v3ident`]
v3ident
:
Option
<
RsaIdentity
>
,
}
impl
AuthorityBuilder
{
/// Make a new AuthorityBuilder with no fields set.
pub
fn
new
()
->
Self
{
Self
::
default
()
}
/// Set the name on this AuthorityBuilder.
///
/// This field is required.
pub
fn
name
(
&
mut
self
,
name
:
&
str
)
->
&
mut
Self
{
self
.name
=
Some
(
name
.to_owned
());
self
}
/// Set the v3 RSA identity of this AuthorityBuilder.
///
/// This field is required.
pub
fn
v3ident
(
&
mut
self
,
key
:
RsaIdentity
)
->
&
mut
Self
{
self
.v3ident
=
Some
(
key
);
self
}
/// Try to build an [`Authority`].
pub
fn
build
(
&
self
)
->
Result
<
Authority
>
{
let
name
=
self
.name
.as_ref
()
.ok_or
(
Error
::
BadNetworkConfig
(
"Missing authority name"
))
?
.clone
();
let
v3ident
=
self
.v3ident
.ok_or
(
Error
::
BadNetworkConfig
(
"Missing v3 identity key."
))
?
;
Ok
(
Authority
{
name
,
v3ident
})
}
}
#[cfg(test)]
mod
test
{
use
super
::
*
;
...
...
@@ -74,7 +127,11 @@ mod test {
fn
authority
()
{
let
key1
:
RsaIdentity
=
[
9_u8
;
20
]
.into
();
let
key2
:
RsaIdentity
=
[
10_u8
;
20
]
.into
();
let
auth
=
Authority
::
new
(
"example"
.into
(),
key1
.clone
());
let
auth
=
Authority
::
builder
()
.name
(
"example"
)
.v3ident
(
key1
)
.build
()
.unwrap
();
assert_eq!
(
auth
.v3ident
(),
&
key1
);
...
...
tor-dirmgr/src/config.rs
View file @
c10de0c3
...
...
@@ -152,39 +152,43 @@ impl NetDirConfigBuilder {
}
/// Set the network information (authorities and fallbacks) from `config`.
pub
fn
set_network_config
(
&
mut
self
,
config
:
NetworkConfig
)
{
pub
fn
set_network_config
(
&
mut
self
,
config
:
NetworkConfig
)
->
&
mut
Self
{
self
.network
=
config
;
self
}
/// Set the timining information that we use for deciding when to
/// attempt and retry downloads.
pub
fn
set_timing_config
(
&
mut
self
,
timing
:
DownloadScheduleConfig
)
{
pub
fn
set_timing_config
(
&
mut
self
,
timing
:
DownloadScheduleConfig
)
->
&
mut
Self
{
self
.timing
=
timing
;
self
}
/// Use `path` as the directory to use for current directory files.
pub
fn
set_cache_path
(
&
mut
self
,
path
:
&
Path
)
{
pub
fn
set_cache_path
(
&
mut
self
,
path
:
&
Path
)
->
&
mut
Self
{
self
.cache_path
=
Some
(
path
.to_path_buf
());
self
}
/// Try to use the default cache path.
///
/// This will be ~/.cache/arti on unix, and in other suitable
/// locations on other platforms.
pub
fn
use_default_cache_path
(
&
mut
self
)
->
Result
<
()
>
{
pub
fn
use_default_cache_path
(
&
mut
self
)
->
Result
<
&
mut
Self
>
{
let
pd
=
directories
::
ProjectDirs
::
from
(
"org"
,
"torproject"
,
"Arti"
)
.ok_or
(
Error
::
DirectoryNotPresent
)
?
;
self
.cache_path
=
Some
(
pd
.cache_dir
()
.into
());
Ok
(
()
)
Ok
(
self
)
}
///
Consum
e this builder
and return
a NetDirConfig that can be used
///
Us
e this builder
to produce
a NetDirConfig that can be used
/// to load directories
pub
fn
finalize
(
self
)
->
Result
<
NetDirConfig
>
{
pub
fn
finalize
(
&
self
)
->
Result
<
NetDirConfig
>
{
let
cache_path
=
self
.cache_path
.as_ref
()
.ok_or
(
Error
::
BadNetworkConfig
(
"No cache path configured"
))
?
;
if
self
.network.authority
.is_empty
()
{
...
...
@@ -195,9 +199,9 @@ impl NetDirConfigBuilder {
}
Ok
(
NetDirConfig
{
cache_path
,
network
:
self
.network
,
timing
:
self
.timing
,
cache_path
:
cache_path
.clone
()
,
network
:
self
.network
.clone
()
,
timing
:
self
.timing
.clone
()
,
})
}
}
...
...
@@ -279,12 +283,41 @@ mod fallbacks {
.expect
(
"Bad hex in built-in fallback list"
);
let
ed
=
Ed25519Identity
::
from_bytes
(
&
ed
)
.expect
(
"Wrong length in built-in fallback list"
);
let
ports
=
ports
let
mut
bld
=
FallbackDir
::
builder
();
bld
.rsa_identity
(
rsa
)
.ed_identity
(
ed
);
ports
.iter
()
.map
(|
s
|
s
.parse
()
.expect
(
"Bad socket address in fallbacklist"
))
.collect
();
FallbackDir
::
new
(
rsa
,
ed
,
ports
)
.for_each
(|
p
|
{
bld
.orport
(
p
);
});
bld
.build
()
.expect
(
"Unable to build default fallback directory!?"
)
}
include!
(
"fallback_dirs.inc"
)
}
}
#[cfg(test)]
mod
test
{
use
super
::
*
;
use
tempdir
::
TempDir
;
#[test]
fn
simplest_config
()
->
Result
<
()
>
{
let
tmp
=
TempDir
::
new
(
"arti-config"
)
.unwrap
();
let
dir
=
NetDirConfigBuilder
::
new
()
.set_cache_path
(
tmp
.path
())
.finalize
()
?
;
assert!
(
dir
.authorities
()
.len
()
>=
3
);
assert!
(
dir
.fallbacks
()
.len
()
>=
3
);
// TODO: verify other defaults.
Ok
(())
}
}
tor-netdir/src/fallback.rs
View file @
c10de0c3
...
...
@@ -5,6 +5,8 @@
//! "Fallback Directory" to retreive its initial information about the
//! network.
use
crate
::{
Error
,
Result
};
use
tor_llcrypto
::
pk
::
ed25519
::
Ed25519Identity
;
use
tor_llcrypto
::
pk
::
rsa
::
RsaIdentity
;
...
...
@@ -28,18 +30,71 @@ pub struct FallbackDir {
orports
:
Vec
<
SocketAddr
>
,
}
/// A Builder object for constructing a [`FallbackDir`].
#[derive(Debug,
Clone,
Default)]
pub
struct
FallbackDirBuilder
{
/// See [`FallbackDir::rsa_identity`]
rsa_identity
:
Option
<
RsaIdentity
>
,
/// See [`FallbackDir::ed_identity`]
ed_identity
:
Option
<
Ed25519Identity
>
,
/// See [`FallbackDir::orports`]
orports
:
Vec
<
SocketAddr
>
,
}
impl
FallbackDir
{
/// Construct a new FallbackDir
pub
fn
new
(
rsa_identity
:
RsaIdentity
,
ed_identity
:
Ed25519Identity
,
orports
:
Vec
<
SocketAddr
>
,
)
->
Self
{
FallbackDir
{
rsa_identity
,
ed_identity
,
orports
,
/// Return a builder that can be used to make a `FallbackDir`.
pub
fn
builder
()
->
FallbackDirBuilder
{
FallbackDirBuilder
::
new
()
}
}
impl
FallbackDirBuilder
{
/// Make a new FallbackDirBuilder.
///
/// You only need to use this if you're using a non-default set of
/// fallback directories.
pub
fn
new
()
->
Self
{
Self
::
default
()
}
/// Set the RSA identity for this fallback directory.
///
/// This field is required.
pub
fn
rsa_identity
(
&
mut
self
,
rsa_identity
:
RsaIdentity
)
->
&
mut
Self
{
self
.rsa_identity
=
Some
(
rsa_identity
);
self
}
/// Set the Ed25519 identity for this fallback directory.
///
/// This field is required.
pub
fn
ed_identity
(
&
mut
self
,
ed_identity
:
Ed25519Identity
)
->
&
mut
Self
{
self
.ed_identity
=
Some
(
ed_identity
);
self
}
/// Add a single OR port for this fallback directory.
///
/// This field is required, and may be called more than once.
pub
fn
orport
(
&
mut
self
,
orport
:
SocketAddr
)
->
&
mut
Self
{
self
.orports
.push
(
orport
);
self
}
/// Try to construct a [`FallbackDir`] from this builder.
pub
fn
build
(
&
self
)
->
Result
<
FallbackDir
>
{
let
rsa_identity
=
self
.rsa_identity
.as_ref
()
.ok_or
(
Error
::
BadArgument
(
"Missing RSA identity on fallback directory"
,
))
?
;
let
ed_identity
=
self
.ed_identity
.as_ref
()
.ok_or
(
Error
::
BadArgument
(
"Missing ed25519 identity on fallback directory"
,
))
?
;
let
orports
=
self
.orports
.clone
();
if
orports
.is_empty
()
{
return
Err
(
Error
::
BadArgument
(
"No OR ports on fallback directory"
));
}
Ok
(
FallbackDir
{
rsa_identity
:
*
rsa_identity
,
ed_identity
:
*
ed_identity
,
orports
,
})
}
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment