tor-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
February 2018
- 19 participants
- 1579 discussions

[tor/release-0.3.2] Add Link protocol version 5 to the supported protocols list in protover.c
by nickm@torproject.org 01 Feb '18
by nickm@torproject.org 01 Feb '18
01 Feb '18
commit a8e5e3a492378f6a9a2b4d55a4e7e5bab3f9dca4
Author: teor <teor2345(a)gmail.com>
Date: Tue Jan 30 01:51:03 2018 +1100
Add Link protocol version 5 to the supported protocols list in protover.c
Part of #25070, bugfix on 0.3.1.1-alpha.
---
src/or/protover.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/or/protover.c b/src/or/protover.c
index 094609269..033e9063a 100644
--- a/src/or/protover.c
+++ b/src/or/protover.c
@@ -292,7 +292,7 @@ protover_get_supported_protocols(void)
"HSDir=1-2 "
"HSIntro=3-4 "
"HSRend=1-2 "
- "Link=1-4 "
+ "Link=1-5 "
"LinkAuth=1,3 "
"Microdesc=1-2 "
"Relay=1-2";
1
0

[tor/release-0.3.2] Merge remote-tracking branch 'teor/bug25070_031' into maint-0.3.1
by nickm@torproject.org 01 Feb '18
by nickm@torproject.org 01 Feb '18
01 Feb '18
commit 9cbc40e37675e77a654bad88f99959873759b9fd
Merge: 5fc0437e7 9656ad323
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu Feb 1 15:28:11 2018 -0500
Merge remote-tracking branch 'teor/bug25070_031' into maint-0.3.1
changes/bug25070 | 3 +++
src/or/protover.c | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
1
0

[tor/release-0.3.1] Add Link protocol version 5 to the supported protocols list in protover.c
by nickm@torproject.org 01 Feb '18
by nickm@torproject.org 01 Feb '18
01 Feb '18
commit a8e5e3a492378f6a9a2b4d55a4e7e5bab3f9dca4
Author: teor <teor2345(a)gmail.com>
Date: Tue Jan 30 01:51:03 2018 +1100
Add Link protocol version 5 to the supported protocols list in protover.c
Part of #25070, bugfix on 0.3.1.1-alpha.
---
src/or/protover.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/or/protover.c b/src/or/protover.c
index 094609269..033e9063a 100644
--- a/src/or/protover.c
+++ b/src/or/protover.c
@@ -292,7 +292,7 @@ protover_get_supported_protocols(void)
"HSDir=1-2 "
"HSIntro=3-4 "
"HSRend=1-2 "
- "Link=1-4 "
+ "Link=1-5 "
"LinkAuth=1,3 "
"Microdesc=1-2 "
"Relay=1-2";
1
0

01 Feb '18
commit 31542cc306ea6d7f4ca629fccd9bcd536573f6d8
Merge: 61cb2993d 9cbc40e37
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu Feb 1 15:28:17 2018 -0500
Merge branch 'maint-0.3.1' into maint-0.3.2
changes/bug25070 | 3 +++
src/or/protover.c | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
1
0

[tor/release-0.3.2] Merge branch 'maint-0.3.2' into release-0.3.2
by nickm@torproject.org 01 Feb '18
by nickm@torproject.org 01 Feb '18
01 Feb '18
commit 1a4876587eb351d51208c5dd93aa37a1e021b8cf
Merge: df37b9333 31542cc30
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu Feb 1 15:28:17 2018 -0500
Merge branch 'maint-0.3.2' into release-0.3.2
changes/bug25070 | 3 +++
src/or/protover.c | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
1
0

[translation/tor-browser-manual_completed] Update translations for tor-browser-manual_completed
by translation@torproject.org 01 Feb '18
by translation@torproject.org 01 Feb '18
01 Feb '18
commit ce884dea8a10c6f2dbae91848979a4af21f5bbaf
Author: Translation commit bot <translation(a)torproject.org>
Date: Thu Feb 1 20:20:37 2018 +0000
Update translations for tor-browser-manual_completed
---
sv/sv.po | 1818 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 1818 insertions(+)
diff --git a/sv/sv.po b/sv/sv.po
new file mode 100644
index 000000000..1b0d391b4
--- /dev/null
+++ b/sv/sv.po
@@ -0,0 +1,1818 @@
+# Translators:
+# cryptohead <cryptohead(a)gmail.com>, 2016
+# Alexandra <alexandra_fischer90(a)hotmail.com>, 2016
+# WinterFairy <winterfairy(a)riseup.net>, 2016
+# Jonatan Nyberg, 2016
+# Daniel Sjöberg <sjbrg(a)protonmail.com>, 2016
+# Yoga Andersson <yoga.andersson(a)gmail.com>, 2016
+# Nikolai Stenfors <nikolai.stenfors(a)bahnhof.se>, 2016
+# Jacob Andersson <jacob.c.andersson(a)protonmail.com>, 2016
+# Bo Serrander <bserrander(a)gmail.com>, 2017
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2016-12-06 16:36-0600\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Bo Serrander <bserrander(a)gmail.com>, 2017\n"
+"Language-Team: Swedish (https://www.transifex.com/otf/teams/1519/sv/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: sv\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
+msgctxt "_"
+msgid "translator-credits"
+msgstr "Lista med översättare"
+
+#: about-tor-browser.page:7
+msgid "Learn what Tor Browser can do to protect your privacy and anonymity"
+msgstr ""
+"Ta reda på vad Tor-webbläsaren kan göra för att skydda din integritet och "
+"anonymitet"
+
+#: about-tor-browser.page:10
+msgid "About Tor Browser"
+msgstr "Om Tor-webbläsare"
+
+#: about-tor-browser.page:12
+msgid ""
+"Tor Browser uses the Tor network to protect your privacy and anonymity. "
+"Using the Tor network has two main properties:"
+msgstr ""
+"Tor webbläsare använder Tor nätverket för att skydda din integritet och din "
+"anonymitet. Tor nätverk har två huvudsakliga egenskaper:"
+
+#: about-tor-browser.page:18
+msgid ""
+"Your internet service provider, and anyone watching your connection locally,"
+" will not be able to track your internet activity, including the names and "
+"addresses of the websites you visit."
+msgstr ""
+"Din Internetleverantör, och alla som bevakar på din anslutning lokalt, "
+"kommer inte att kunna spåra din Internet-aktivitet, inklusive namn och "
+"adresser till de webbplatser du besöker."
+
+#: about-tor-browser.page:25
+msgid ""
+"The operators of the websites and services that you use, and anyone watching"
+" them, will see a connection coming from the Tor network instead of your "
+"real Internet (IP) address, and will not know who you are unless you "
+"explicitly identify yourself."
+msgstr ""
+"Operatörerna av de webbplatser och tjänster som du använder, och alla som "
+"bevakar dem, kommer att se en förbindelse som kommer från Tor-nätverket "
+"istället för din riktiga Internet (IP) adress, och kommer inte att veta vem "
+"du är om du inte uttryckligen identifiera dig."
+
+#: about-tor-browser.page:34
+msgid ""
+"In addition, Tor Browser is designed to prevent websites from "
+"“fingerprinting” or identifying you based on your browser configuration."
+msgstr ""
+"Dessutom är Tor Browser utformad för att förhindra webbplatser från "
+"\"fingeravtryck\" eller identifiera dig baserat på din "
+"webbläsarkonfiguration."
+
+#: about-tor-browser.page:39
+msgid ""
+"By default, Tor Browser does not keep any browsing history. Cookies are only"
+" valid for a single session (until Tor Browser is exited or a <link xref"
+"=\"managing-identities#new-identity\">New Identity</link> is requested)."
+msgstr ""
+"Som standard behåller Tor Browser inte någon webbhistorik . Cookies är "
+"endast giltig för en enda session (tills Tor Browser avslutas eller en <link"
+" xref=\"managing-identities#new-identity\">Ny identitet </link> begärs)."
+
+#: about-tor-browser.page:50
+msgid "How Tor works"
+msgstr "Hur Tor fungerar"
+
+#: about-tor-browser.page:52
+msgid ""
+"Tor is a network of virtual tunnels that allows you to improve your privacy "
+"and security on the Internet. Tor works by sending your traffic through "
+"three random servers (also known as <em>relays</em>) in the Tor network. The"
+" last relay in the circuit (the “exit relay”) then sends the traffic out "
+"onto the public Internet."
+msgstr ""
+"Tor är ett nätverk av virtuella tunnlar som tillåter dig att förbättra din "
+"integritet och säkerhet på Internet. Tor fungerar genom att skicka din "
+"trafik genom tre slump servrar (även känd som <em>reläer</em>) i Tor-"
+"nätverket. Den sista relän i kretsen (\"exit relä\") skickar sedan trafiken "
+"ut på det publika Internet."
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: about-tor-browser.page:59
+msgctxt "_"
+msgid ""
+"external ref='media/how-tor-works.png' "
+"md5='6fe4151a88b7a518466f0582e40ccc8c'"
+msgstr ""
+"extern ref='media/how-tor-works.png' md5='6fe4151a88b7a518466f0582e40ccc8c'"
+
+#: about-tor-browser.page:60
+msgid ""
+"The image above illustrates a user browsing to different websites over Tor. "
+"The green middle computers represent relays in the Tor network, while the "
+"three keys represent the layers of encryption between the user and each "
+"relay."
+msgstr ""
+"Bilden ovan visar en användare som surfar till olika webbplatser över Tor. "
+"De gröna mellan datorerna representerar reläer i Tor-nätverket, medan de tre"
+" knapparna representerar lagren av kryptering mellan användaren och varje "
+"relä."
+
+#: bridges.page:6
+msgid "Learn what bridges are and how to get them"
+msgstr "Lär dig vad bryggor är och hur man får tillgång till dem"
+
+#: bridges.page:10
+msgid "Bridges"
+msgstr "Broar"
+
+#: bridges.page:12
+msgid ""
+"Most <link xref=\"transports\">Pluggable Transports</link>, such as obfs3 "
+"and obfs4, rely on the use of “bridge” relays. Like ordinary Tor relays, "
+"bridges are run by volunteers; unlike ordinary relays, however, they are not"
+" listed publicly, so an adversary cannot identify them easily. Using bridges"
+" in combination with pluggable transports helps to disguise the fact that "
+"you are using Tor."
+msgstr ""
+"Flesta <link xref = \"transports\">Pluggbara transporter</link>, som obfs3 "
+"och obfs4, är beroende av användningen av \"bro\"-reläer. Som vanliga Tor-"
+"reläer körs broar av volontärer. Till skillnad från vanliga reläer är de "
+"inte listade offentligt, så en motståndare kan inte identifiera dem enkelt. "
+"Användning av broar i kombination med pluggbara transporter hjälper till att"
+" dölja det faktum att du använder Tor."
+
+#: bridges.page:21
+msgid ""
+"Other pluggable transports, like meek, use different anti-censorship "
+"techniques that do not rely on bridges. You do not need to obtain bridge "
+"addresses in order to use these transports."
+msgstr ""
+"Andra pluggbara transporter, som meek, använder olika anticensurtekniker som"
+" inte bygger på broar. Du behöver inte få broadresser för att kunna använda "
+"dessa transporter."
+
+#: bridges.page:28
+msgid "Getting bridge addresses"
+msgstr "Skaffar bryggadresser"
+
+#: bridges.page:29
+msgid ""
+"Because bridge addresses are not public, you will need to request them "
+"yourself. You have two options:"
+msgstr ""
+"Eftersom bryggadresser inte är offentliga, måste du begära dem själv. Du har"
+" två alternativ:"
+
+#: bridges.page:36
+msgid ""
+"Visit <link "
+"href=\"https://bridges.torproject.org/\">https://bridges.torproject.org/</link>"
+" and follow the instructions, or"
+msgstr ""
+"Besök <link "
+"href=\"https://bridges.torproject.org/\">https://bridges.torproject.org/</link>"
+" och följ instruktionerna, eller"
+
+#: bridges.page:42
+msgid ""
+"Email bridges(a)torproject.org from a Gmail, Yahoo, or Riseup email address, "
+"or"
+msgstr ""
+"Maila bridges(a)torproject.org från en Gmail, Yahoo eller RiseUp e-postadress "
+"eller"
+
+#: bridges.page:51
+msgid "Entering bridge addresses"
+msgstr "Skriver in broadresser"
+
+#: bridges.page:52
+msgid ""
+"Once you have obtained some bridge addresses, you will need to enter them "
+"into Tor Launcher."
+msgstr "När du har fått några broadresser, måste du ange dem i Tor Launcher."
+
+#: bridges.page:57
+msgid ""
+"Choose “yes” when asked if your Internet Service Provider blocks connections"
+" to the Tor network. Select “Use custom bridges” and enter each bridge "
+"address on a separate line."
+msgstr ""
+"Välj \"ja\" på frågan om din Internet-tjänsteleverantören blockerar "
+"anslutningar till Tor-nätverket. Välj \"Använd egna bryggor\" och ange en "
+"bryggadress per rad."
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: bridges.page:63
+msgctxt "_"
+msgid ""
+"external ref='media/tor-launcher-custom-bridges_en-US.png' "
+"md5='93365c2aa3fb4d627497e83f28a39b7e'"
+msgstr ""
+"extern ref='media/tor-launcher-custom-bridges_en-US.png' "
+"md5='93365c2aa3fb4d627497e83f28a39b7e'"
+
+#: bridges.page:65
+msgid ""
+"Click “Connect”. Using bridges may slow down the connection compared to "
+"using ordinary Tor relays. If the connection fails, the bridges you received"
+" may be down. Please use one of the above methods to obtain more bridge "
+"addresses, and try again."
+msgstr ""
+"Klicka på \"Anslut\". Det kan gå långsammare när du använder bryggor "
+"jämntemot vanliga Tor-reläer. Om anslutningen misslyckas kan broadressen du "
+"fick vara nere. Använd en av metoderna ovan för att få fler broadresser och "
+"försök igen."
+
+#: circumvention.page:6
+msgid "What to do if the Tor network is blocked"
+msgstr "Vad du ska göra ifall Tor nätverket är blockerat"
+
+#: circumvention.page:10
+msgid "Circumvention"
+msgstr "Kringgående"
+
+#: circumvention.page:12
+msgid ""
+"Direct access to the Tor network may sometimes be blocked by your Internet "
+"Service Provider or by a government. Tor Browser includes some circumvention"
+" tools for getting around these blocks. These tools are called “pluggable "
+"transports”. See the <link xref=\"transports\">Pluggable Transports</link> "
+"page for more information on the types of transport that are currently "
+"available."
+msgstr ""
+"Direktåtkomst till Tor-nätverket kan ibland blockeras av din "
+"Internetleverantör eller av en regering. Tor Browser innehåller några "
+"kringgående verktyg för att komma runt dessa blockeringar. Dessa verktyg "
+"kallas \"pluggbara transporter\". Se sidan <link "
+"xref=\"transports\">Pluggbara transporter</link> för mer information om "
+"vilka transporttyper som för närvarande finns tillgängliga."
+
+#: circumvention.page:22
+msgid "Using pluggable transports"
+msgstr "Använder pluggbara transporter"
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: circumvention.page:26 first-time.page:35
+msgctxt "_"
+msgid ""
+"external ref='media/circumvention/configure.png' "
+"md5='519d888303eadfe4cb03f178aedd90f5'"
+msgstr ""
+"extern ref='media/circumvention/configure.png' "
+"md5='519d888303eadfe4cb03f178aedd90f5'"
+
+#: circumvention.page:28
+msgid ""
+"To use pluggable transports, click \"Configure\" in the Tor Launcher window "
+"that appears when you first run Tor Browser."
+msgstr ""
+"För att använda pluggbara transporter, klicka på \"Konfigurera\" i Tor "
+"Launcher-fönstret som visas när du först kör Tor Browser."
+
+#: circumvention.page:33
+msgid ""
+"You can also configure pluggable transports while Tor Browser is running, by"
+" clicking on the green onion near your address bar and selecting “Tor "
+"Network Settings”."
+msgstr ""
+"Du kan också konfigurera pluggbara transporter medan Tor Browser körs, genom"
+" att klicka på den gröna löken i närheten av adressfältet och välja \"Tor "
+"nätverk inställningar\"."
+
+#: circumvention.page:41
+msgid ""
+"Select “yes” when asked if your Internet Service Provider blocks connections"
+" to the Tor network."
+msgstr ""
+"Välj \"ja\" på frågan om din Internet-tjänsteleverantören blockerar "
+"anslutningar till Tor-nätverket."
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: circumvention.page:49
+msgctxt "_"
+msgid ""
+"external ref='media/circumvention/bridges.png' "
+"md5='910cdd5e45860b81a1ad4739c589a195'"
+msgstr ""
+"extern ref='media/circumvention/bridges.png' "
+"md5='910cdd5e45860b81a1ad4739c589a195'"
+
+#: circumvention.page:51
+msgid ""
+"Select “Connect with provided bridges”. Tor Browser currently has six "
+"pluggable transport options to choose from."
+msgstr ""
+"Välj \"Anslut med tillhandahållna broar\". Tor Browser har för närvarande "
+"sex pluggbara transport alternativ att välja mellan."
+
+#: circumvention.page:60
+msgid "Which transport should I use?"
+msgstr "Vilka transporter ska jag använda?"
+
+#: circumvention.page:61
+msgid ""
+"Each of the transports listed in Tor Launcher’s menu works in a different "
+"way (for more details, see the <link xref=\"transports\">Pluggable "
+"Transports</link> page), and their effectiveness depends on your individual "
+"circumstances."
+msgstr ""
+"Var och en av de transporter som anges i Tor Launcher-menyn fungerar på ett "
+"annat sätt (för mer information, se <link xref=\"transports\">Pluggbara "
+"transporter</link>-sidan) och deras effektivitet beror på dina individuella "
+"omständigheter."
+
+#: circumvention.page:67
+msgid ""
+"If you are trying to circumvent a blocked connection for the first time, you"
+" should try the different transports: obfs3, obfs4, ScrambleSuit, fte, meek-"
+"azure, meek-amazon."
+msgstr ""
+"Om du försöker att kringgå en blockerad anslutning för första gången, bör du"
+" prova olika transporter: obfs3, obfs4, ScrambleSuit, fte, meed-azure, meek-"
+"amazon."
+
+#: circumvention.page:72
+msgid ""
+"If you try all of these options, and none of them gets you online, you will "
+"need to enter bridge addresses manually. Read the <link "
+"xref=\"bridges\">Bridges</link> section to learn what bridges are and how to"
+" obtain them."
+msgstr ""
+"Om du försöker alla dessa alternativ, och ingen av dem får dig på nätet, "
+"måste du ange broadresser manuellt. Läs avsnittet <link "
+"xref=\"bridges\">Broar</link> för att lära dig vilka broar som finns och hur"
+" man hämtar dem."
+
+#: downloading.page:7
+msgid "How to download Tor Browser"
+msgstr "Hur du laddar ner Tor"
+
+#: downloading.page:10
+msgid "Downloading"
+msgstr "Hämtar"
+
+#: downloading.page:12
+msgid ""
+"The safest and simplest way to download Tor Browser is from the official Tor"
+" Project website at https://www.torproject.org. Your connection to the site "
+"will be secured using <link xref=\"secure-connections\">HTTPS</link>, which "
+"makes it much harder for somebody to tamper with."
+msgstr ""
+"Det säkraste och enklaste sättet att ladda ner Tor Browser är från den "
+"officiella Tor Project-webbplatsen på https://www.torproject.org. Din "
+"anslutning till webbplatsen kommer att säkras med hjälp av <link xref"
+"=\"secure-connections\">HTTPS</link>, vilket gör det mycket svårare för "
+"någon att manipulera med."
+
+#: downloading.page:19
+msgid ""
+"However, there may be times when you cannot access the Tor Project website: "
+"for example, it could be blocked on your network. If this happens, you can "
+"use one of the alternative download methods listed below."
+msgstr ""
+"Det kan dock finnas tillfällen då du inte kan komma åt Tor Project-"
+"webbplatsen. Det kan till exempel vara blockerat på ditt nätverk. Om det "
+"händer kan du använda en av de alternativa hämtningsmetoderna nedan."
+
+#: downloading.page:27
+msgid "GetTor"
+msgstr "GetTor"
+
+#: downloading.page:28
+msgid ""
+"GetTor is a service that automatically responds to messages with links to "
+"the latest version of Tor Browser, hosted at a variety of locations, such as"
+" Dropbox, Google Drive and Github.."
+msgstr ""
+"GetTor är en tjänst som automatiskt svarar på meddelanden med länkar till "
+"den senaste versionen av Tor Browser, som finns på flera olika platser, till"
+" exempel Dropbox, Google Drive och Github."
+
+#: downloading.page:34
+msgid "To use GetTor via email:"
+msgstr "För att använda GetTor via e-post:"
+
+#: downloading.page:39
+msgid ""
+"Send an email to gettor(a)torproject.org, and in the body of the message "
+"simply write “windows”, “osx”, or “linux”, (without quotation marks) "
+"depending on your operating system."
+msgstr ""
+"Skicka ett e-post till gettor(a)torproject.org med något av följande i "
+"meddelandetexten \"winows\", \"osx\" eller \"linux\" (ta inte med "
+"citattecken) beroende på ditt val av operativsystem."
+
+#: downloading.page:46
+msgid ""
+"GetTor will respond with an email containing links from which you can "
+"download the Tor Browser package, the cryptographic signature (needed for "
+"verifying the download), the fingerprint of the key used to make the "
+"signature, and the package’s checksum. You may be offered a choice of "
+"“32-bit” or “64-bit” software: this depends on the model of the computer you"
+" are using."
+msgstr ""
+"GetTor svarar med ett e-postmeddelande med länkar från vilka du kan hämta "
+"Tor Browser-paketet, kryptografiska signaturen (behövs för att verifiera "
+"hämtningen), fingeravtryck av den nyckel som används för att göra signaturen"
+" och paketets kontrollsumma. Du kan erbjudas ett val av \"32-bitars\" eller "
+"\"64-bitars\" programvara: detta beror på vilken modell av datorn du "
+"använder."
+
+#: downloading.page:57
+msgid "To use GetTor via Twitter:"
+msgstr "För att använda GetTor via Twitter:"
+
+#: downloading.page:62
+msgid ""
+"To get links for downloading Tor Browser in English for OS X, send a Direct "
+"Message to @get_tor with the words \"osx en\" in it (you don't need to "
+"follow the account)."
+msgstr ""
+"För att få länkar för att hämta Tor Browser på engelska för OS X, skicka ett"
+" direktmeddelande till @get_tor med orden \"osx en\" i det (du behöver inte "
+"följa kontot)."
+
+#: downloading.page:70
+msgid "To use GetTor via Jabber/XMPP (Tor Messenger, Jitsi, CoyIM):"
+msgstr "För att använda GetTor via Jabber/XMPP (Tor Messenger, Jitsi, CoyIM):"
+
+#: downloading.page:75
+msgid ""
+"To get links for downloading Tor Browser in Chinese for Linux, send a "
+"message to gettor(a)torproject.org with the words \"linux zh\" in it."
+msgstr ""
+"För att få länkar för att hämta Tor Browser på kinesiska för Linux, skicka "
+"ett meddelande till gettor(a)torproject.org med orden \"linux zh\" i det."
+
+#: downloading.page:84
+msgid "Satori"
+msgstr "Satori"
+
+#: downloading.page:85
+msgid ""
+"Satori is an add-on for the Chrome or Chromium browsers that allows you to "
+"download several security and privacy programs from different sources."
+msgstr ""
+"Satori är ett tillägg för Chrome eller Chromium webbläsarna som låter dig "
+"hämta flera säkerhets- och sekretessprogram från olika källor."
+
+#: downloading.page:90
+msgid "To download Tor Browser using Satori:"
+msgstr "Ladda ner Tor med Satori:"
+
+#: downloading.page:95
+msgid "Install Satori from the Chrome App Store."
+msgstr "Installera Satori med Chrome App Store."
+
+#: downloading.page:100
+msgid "Select Satori from your browser’s Apps menu."
+msgstr "Välj Satori från din webbläsares Appar-meny."
+
+#: downloading.page:105
+msgid ""
+"When Satori opens, click on your preferred language. A menu will open "
+"listing the available downloads for that language. Find the entry for Tor "
+"Browser under the name of your operating system. Select either “A” or “B” "
+"after the name of the program — each one represents a different source from "
+"which to get the software. Your download will then begin."
+msgstr ""
+"När Satori öppnas klickar du på ditt önskade språk. Kommer en meny öppnas "
+"med listan över tillgängliga hämtningar för det språket. Hitta posten för "
+"Tor Browser under namnet på ditt operativsystem. Välj antingen \"A\" eller "
+"\"B\" efter programmets namn - var och en representerar en annan källa för "
+"att hämta mjukvaran. Din nedladdning startar sedan."
+
+#: downloading.page:115
+msgid ""
+"Wait for your download to finish, then find the “Generate Hash” section in "
+"Satori’s menu and click “Select Files”."
+msgstr ""
+"Vänta på att din hämtning är klar och hitta sedan avsnittet \"Generera "
+"Hash\" i Satori-menyn och klicka på \"Välj filer\"."
+
+#: downloading.page:121
+msgid ""
+"Select the downloaded Tor Browser file. Satori will display the checksum of "
+"the file, which you should compare with the software’s original checksum: "
+"you can find this by clicking the word “checksum” after the link you clicked"
+" on to start the download. If the checksums match, your download was "
+"successful, and you can <link xref=\"first-time\">begin using Tor "
+"Browser</link>. If they do not match, you may need to try downloading again,"
+" or from a different source."
+msgstr ""
+"Välj den hämtade Tor Browser-filen. Satori kommer att visa kontrollsumma för"
+" filen, som du bör jämföra med programmets ursprungliga kontrollsumma: du "
+"kan hitta det genom att klicka på ordet \"checksum\" efter länken du "
+"klickade på för att starta hämtningen. Om kontrollsummorna matchar var din "
+"hämtning framgångsrik, och du kan <link xref=\"first-time\">börja använda "
+"Tor Browser</link>. Om de inte matchar kan du behöva försöka hämta igen, "
+"eller från en annan källa."
+
+#: first-time.page:7
+msgid "Learn how to use Tor Browser for the first time"
+msgstr "Lär dig använda Tor för första gången"
+
+#: first-time.page:10
+msgid "Running Tor Browser for the first time"
+msgstr "Att använda Tor för första gången"
+
+#: first-time.page:12
+msgid ""
+"When you run Tor Browser for the first time, you will see the Tor Network "
+"Settings window. This offers you the option to connect directly to the Tor "
+"network, or to configure Tor Browser for your connection."
+msgstr ""
+"När du kör Tor Browser för första gången ser du fönstret Tor Network "
+"Settings. Detta ger dig möjlighet att ansluta direkt till Tor-nätverket "
+"eller konfigurera Tor Browser för din anslutning."
+
+#: first-time.page:19
+msgid "Connect"
+msgstr "Anslut"
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: first-time.page:21 troubleshooting.page:18
+msgctxt "_"
+msgid ""
+"external ref='media/first-time/connect.png' "
+"md5='9d07068f751a3bfd274365a4ba8d90ca'"
+msgstr ""
+"external ref='media/first-time/connect.png' "
+"md5='9d07068f751a3bfd274365a4ba8d90ca'"
+
+#: first-time.page:23
+msgid ""
+"In most cases, choosing \"Connect\" will allow you to connect to the Tor "
+"network without any further configuration. Once clicked, a status bar will "
+"appear, showing Tor’s connection progress. If you are on a relatively fast "
+"connection, but this bar seems to get stuck at a certain point, see the "
+"<link xref=\"troubleshooting\">Troubleshooting</link> page for help solving "
+"the problem."
+msgstr ""
+"I de flesta fall kan du välja \"Anslut\" så att du kan ansluta till Tor-"
+"nätverket utan ytterligare konfiguration. Efter att du klickat visas ett "
+"statusfält som visar Tors anslutningsframsteg. Om du har en relativt snabb "
+"anslutning, men den här fältet fastnar vid en viss punkt, se sidan <link "
+"xref=\"troubleshooting\">Felsökning</link> för att lösa problemet."
+
+#: first-time.page:33
+msgid "Configure"
+msgstr "Konfigurera"
+
+#: first-time.page:37
+msgid ""
+"If you know that your connection is censored, or uses a proxy, you should "
+"select this option. Tor Browser will take you through a series of "
+"configuration options."
+msgstr ""
+"Om du vet att din anslutning är censurerad eller använder en proxy, ska du "
+"välja det här alternativet. Tor Browser tar dig igenom en rad "
+"konfigurationsalternativ."
+
+#: first-time.page:44
+msgid ""
+"The first screen asks if access to the Tor network is blocked or censored on"
+" your connection. If you do not believe this is the case, select “No”. If "
+"you know your connection is censored, or you have tried and failed to "
+"connect to the Tor network and no other solutions have worked, select “Yes”."
+" You will then be taken to the <link "
+"xref=\"circumvention\">Circumvention</link> screen to configure a pluggable "
+"transport."
+msgstr ""
+"Den första skärmen frågar om åtkomst till Tor-nätverket är blockerat eller "
+"censurerat på din anslutning. Om du inte tror detta är fallet, välj \"Nej\"."
+" Om du vet att din anslutning är censurerad, eller om du har försökt och "
+"misslyckats med att ansluta till Tor-nätverket och inga andra lösningar har "
+"fungerat, välj \"Ja\". Du kommer då att tas till skärmen <link "
+"xref=\"circumvention\">Kringgående</link> för att konfigurera en pluggbar "
+"transport."
+
+#: first-time.page:55
+msgid ""
+"The next screen asks if your connection uses a proxy. In most cases, this is"
+" not necessary. You will usually know if you need to answer “Yes”, as the "
+"same settings will be used for other browsers on your system. If possible, "
+"ask your network administrator for guidance. If your connection does not use"
+" a proxy, click “Continue”."
+msgstr ""
+"Nästa skärm frågar om din anslutning använder en proxy. I de flesta fall är "
+"det inte nödvändigt. Du vet vanligen om du behöver svara \"Ja\", eftersom "
+"samma inställningar kommer att användas för andra webbläsare på ditt system."
+" Om möjligt, fråga din nätverksadministratör för vägledning. Om din "
+"anslutning inte använder en proxy, klicka på \"Fortsätt\"."
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: first-time.page:63
+msgctxt "_"
+msgid ""
+"external ref='media/first-time/proxy_question.png' "
+"md5='30853b3e86cfd386bbc32e5b8b45a378'"
+msgstr ""
+"external ref='media/first-time/proxy_question.png' "
+"md5='30853b3e86cfd386bbc32e5b8b45a378'"
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: first-time.page:66
+msgctxt "_"
+msgid ""
+"external ref='media/first-time/proxy.png' "
+"md5='13f21a351cd0aa1cf11aada690f3dc90'"
+msgstr ""
+"external ref='media/first-time/proxy.png' "
+"md5='13f21a351cd0aa1cf11aada690f3dc90'"
+
+#: index.page:6
+msgid "Tor Browser User Manual"
+msgstr "Tor Browser bruksanvisning"
+
+#: known-issues.page:6
+msgid "A list of known issues."
+msgstr "En lista över kända problem"
+
+#: known-issues.page:10
+msgid "Known Issues"
+msgstr "Kända problem"
+
+#: known-issues.page:14
+msgid ""
+"Tor needs your system clock (and your time zone) set to the correct time."
+msgstr ""
+"Tor kräver att din systemklocka (och din tidszon) är inställd på rätt tid."
+
+#: known-issues.page:19
+msgid ""
+"The following firewall software have been known to interfere with Tor and "
+"may need to be temporarily disabled:"
+msgstr ""
+"Följande brandväggsprogram har varit känd för att störa Tor och kan behöva "
+"inaktiveras tillfälligt:"
+
+#: known-issues.page:23
+msgid "Webroot SecureAnywhere"
+msgstr "Webroot SecureAnywhere"
+
+#: known-issues.page:26
+msgid "Kaspersky Internet Security 2012"
+msgstr "Kaspersky Internet Security 2012"
+
+#: known-issues.page:29
+msgid "Sophos Antivirus for Mac"
+msgstr "Sophos Antivirus for Mac"
+
+#: known-issues.page:32
+msgid "Microsoft Security Essentials"
+msgstr "Microsoft säkerhetsväsentligheter"
+
+#: known-issues.page:37
+msgid ""
+"Videos that require Adobe Flash are unavailable. Flash is disabled for "
+"security reasons."
+msgstr ""
+"Videoklipp som kräver Adobe Flash är inte tillgängliga. Flash är inaktiverad"
+" av säkerhetsskäl."
+
+#: known-issues.page:43
+msgid "Tor can not use a bridge if a proxy is set."
+msgstr "Tor kan inte använda en bro om en proxy är inställd."
+
+#: known-issues.page:48
+msgid ""
+"The Tor Browser package is dated January 1, 2000 00:00:00 UTC. This is to "
+"ensure that each software build is exactly reproducible."
+msgstr ""
+"Tor Browser paketet är daterad 1 jan 2000 00:00:00 UTC. Detta för att "
+"säkerställa att varje byggd mjukvara är exakt reproducerbar."
+
+#: known-issues.page:54
+msgid ""
+"To run Tor Browser on Ubuntu, users need to execute a shell script. Open "
+"\"Files\" (Unity's explorer), open Preferences → Behavior Tab → Set \"Run "
+"executable text files when they are opened\" to \"Ask every time\", then "
+"click OK."
+msgstr ""
+"För att köra Tor Browser på Ubuntu måste användarna exekvera ett skalskript."
+" Öppna \"Filer\" (Unity explorer), öppna Inställningar → Beteendeflik → Ange"
+" \"Kör körbara textfiler när de öppnas\" till \"Fråga varje gång\" och "
+"klicka sedan på OK."
+
+#: known-issues.page:62
+msgid ""
+"Tor Browser can also be started from the command line by running the "
+"following command from inside the Tor Browser directory:"
+msgstr ""
+"Tor Browser kan också startas från kommandoraden genom att köra följande "
+"kommando från inuti Tor Browser-katalogen:"
+
+#: known-issues.page:66
+#, no-wrap
+msgid ""
+"\n"
+" ./start-tor-browser.desktop\n"
+" "
+msgstr ""
+"\n"
+" ./start-tor-browser.desktop\n"
+" "
+
+#: managing-identities.page:6
+msgid "Learn how to control personally-identifying information in Tor Browser"
+msgstr ""
+"Lär dig hur du kontrollerar personligt identifierande information i Tor "
+"Browser"
+
+#: managing-identities.page:10
+msgid "Managing identities"
+msgstr "Hantera identiteter"
+
+#: managing-identities.page:12
+msgid ""
+"When you connect to a website, it is not only the operators of that website "
+"who can record information about your visit. Most websites now use numerous "
+"third-party services, including social networking “Like” buttons, analytics "
+"trackers, and advertising beacons, all of which can link your activity "
+"across different sites."
+msgstr ""
+"När du ansluter till en webbplats är det inte bara operatörerna på den "
+"webbplatsen som kan spela in information om ditt besök. De flesta "
+"webbplatser använder nu många tredjepartstjänster, bland annat "
+"\"Gilla\"-knappar för sociala nätverk, analytikerspårare och reklamfiler, "
+"som alla kan länka din aktivitet på olika webbplatser."
+
+#: managing-identities.page:20
+msgid ""
+"Using the Tor network stops observers from being able to discover your exact"
+" location and IP address, but even without this information they might be "
+"able to link different areas of your activity together. For this reason, Tor"
+" Browser includes some additional features that help you control what "
+"information can be tied to your identity."
+msgstr ""
+"Med hjälp av Tor-nätverket hindras observatörer från att kunna upptäcka din "
+"exakta plats och IP-adress, men även utan denna information kan de "
+"eventuellt länka olika delar av din verksamhet tillsammans. Av denna "
+"anledning innehåller Tor Browser några ytterligare funktioner som hjälper "
+"dig att styra vilken information som kan kopplas till din identitet."
+
+#: managing-identities.page:29
+msgid "The URL bar"
+msgstr "Adressfältet"
+
+#: managing-identities.page:30
+msgid ""
+"Tor Browser centers your web experience around your relationship with the "
+"website in the URL bar. Even if you connect to two different sites that use "
+"the same third-party tracking service, Tor Browser will force the content to"
+" be served over two different Tor circuits, so the tracker will not know "
+"that both connections originate from your browser."
+msgstr ""
+"Tor Browser centrerar din webbupplevelse kring ditt förhållande till "
+"webbplatsen i webbläsarfältet. Även om du ansluter till två olika "
+"webbplatser som använder samma tredjeparts spårningstjänst, kommer Tor "
+"Browser att tvinga innehållet som ska serveras över två olika Tor-kretsar, "
+"så spåraren vet inte att båda anslutningarna kommer från din webbläsare."
+
+#: managing-identities.page:38
+msgid ""
+"On the other hand, all connections to a single website address will be made "
+"over the same Tor circuit, meaning you can browse different pages of a "
+"single website in separate tabs or windows, without any loss of "
+"functionality."
+msgstr ""
+"Å andra sidan kommer alla anslutningar till en enda webbplatsadress att "
+"göras över samma Tor-krets, vilket innebär att du kan bläddra i olika sidor "
+"på en enda webbplats i separata flikar eller fönster, utan att det går någon"
+" förlust av funktionaliteten."
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: managing-identities.page:46
+msgctxt "_"
+msgid ""
+"external ref='media/managing-identities/circuit_full.png' "
+"md5='bd46d22de952fee42643be46d3f95928'"
+msgstr ""
+"external ref='media/managing-identities/circuit_full.png' "
+"md5='bd46d22de952fee42643be46d3f95928'"
+
+#: managing-identities.page:48
+msgid ""
+"You can see a diagram of the circuit that Tor Browser is using for the "
+"current tab in the onion menu."
+msgstr ""
+"Du kan se ett diagram över den krets som Tor Browser använder för den "
+"aktuella fliken i onionmenyn."
+
+#: managing-identities.page:55
+msgid "Logging in over Tor"
+msgstr "Logga in över Tor"
+
+#: managing-identities.page:56
+msgid ""
+"Although Tor Browser is designed to enable total user anonymity on the web, "
+"there may be situations in which it makes sense to use Tor with websites "
+"that require usernames, passwords, or other identifying information."
+msgstr ""
+"Även om Tor Browser är utformad för att möjliggöra total användaranonymitet "
+"på webben kan det finnas situationer där det är vettigt att använda Tor med "
+"webbplatser som kräver användarnamn, lösenord eller annan identifierande "
+"information."
+
+#: managing-identities.page:62
+msgid ""
+"If you log into a website using a regular browser, you also reveal your IP "
+"address and geographical location in the process. The same is often true "
+"when you send an email. Logging into your social networking or email "
+"accounts using Tor Browser allows you to choose exactly which information "
+"you reveal to the websites you browse. Logging in using Tor Browser is also "
+"useful if the website you are trying to reach is censored on your network."
+msgstr ""
+"Om du loggar in på en webbplats med en vanlig webbläsare avslöjar du också "
+"din IP-adress och geografiska plats i processen. Detsamma är ofta sant när "
+"du skickar ett mail. Genom att logga in på dina sociala nätverk eller "
+"e-postkonton med hjälp av Tor Browser kan du välja exakt vilken information "
+"du avslöjar för de webbplatser du surfar på. Att logga in med Tor Browser är"
+" också användbart om webbplatsen du försöker nå är censurerad på ditt "
+"nätverk."
+
+#: managing-identities.page:72
+msgid ""
+"When you log in to a website over Tor, there are several points you should "
+"bear in mind:"
+msgstr ""
+"När du loggar in på en webbplats över Tor finns det flera punkter du bör "
+"tänka på: "
+
+#: managing-identities.page:79
+msgid ""
+"See the <link xref=\"secure-connections\">Secure Connections</link> page for"
+" important information on how to secure your connection when logging in."
+msgstr ""
+"Se <link xref=\"secure-connections\">Säkra anslutningar</link>-sidan för "
+"viktig information om hur du säkrar din anslutning när du loggar in."
+
+#: managing-identities.page:87
+msgid ""
+"Tor Browser often makes your connection appear as though it is coming from "
+"an entirely different part of the world. Some websites, such as banks or "
+"email providers, might interpret this as a sign that your account has been "
+"hacked or compromised, and lock you out. The only way to resolve this is by "
+"following the site’s recommended procedure for account recovery, or "
+"contacting the operators and explaining the situation."
+msgstr ""
+"Tor Browser gör att din anslutning ofta visas som om den kommer från en helt"
+" annan del av världen. Vissa webbplatser, till exempel banker eller "
+"e-postleverantörer, kan tolka detta som ett tecken på att ditt konto har "
+"hackats eller kompromissad och låser ut dig. Det enda sättet att lösa det "
+"här är att följa webbplatsens rekommenderade procedur för kontoåterställning"
+" eller kontakta operatörerna och förklara situationen."
+
+#: managing-identities.page:101
+msgid "Changing identities and circuits"
+msgstr "Ändra identiteter och kretsar"
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: managing-identities.page:103
+msgctxt "_"
+msgid ""
+"external ref='media/managing-identities/new_identity.png' "
+"md5='15b01e35fa83185d94b57bf0ccf09d76'"
+msgstr ""
+"external ref='media/managing-identities/new_identity.png' "
+"md5='15b01e35fa83185d94b57bf0ccf09d76'"
+
+#: managing-identities.page:105
+msgid ""
+"Tor Browser features “New Identity” and “New Tor Circuit for this Site” "
+"options, located in the Torbutton menu."
+msgstr ""
+"Tor Browser har alternativet \"Ny identitet\" och \"Ny Tor krets för denna "
+"sida\", som finns i Torbutton-menyn."
+
+#: managing-identities.page:111
+msgid "New Identity"
+msgstr "Ny identitet"
+
+#: managing-identities.page:112
+msgid ""
+"This option is useful if you want to prevent your subsequent browser "
+"activity from being linkable to what you were doing before. Selecting it "
+"will close all your open tabs and windows, clear all private information "
+"such as cookies and browsing history, and use new Tor circuits for all "
+"connections. Tor Browser will warn you that all activity and downloads will "
+"be stopped, so take this into account before clicking “New Identity”."
+msgstr ""
+"Denna inställningen är användbar ifall du vill förebygga din föregående "
+"aktivitet ska vara länkbar med vad du har gjort innan. Vid val av denna "
+"inställningen kommer att stänga alla öppna flikar, fönster, all privat data "
+"som cookies och webbläsar historik kommer att tas bort, och nya Tor kretsar "
+"kommer användas för alla uppkopplingar. Tor webläsaren kommer att varna dig "
+"att all aktivitet och nedladdningar kommer att stoppas, tänk på detta innan "
+"du klicka \"Ny identitet\"."
+
+#: managing-identities.page:123
+msgid "New Tor Circuit for this Site"
+msgstr "Ny Tor-krets för den här webbplatsen"
+
+#: managing-identities.page:124
+msgid ""
+"This option is useful if the <link xref=\"about-tor-browser#how-tor-"
+"works\">exit relay</link> you are using is unable to connect to the website "
+"you require, or is not loading it properly. Selecting it will cause the "
+"currently-active tab or window to be reloaded over a new Tor circuit. Other "
+"open tabs and windows from the same website will use the new circuit as well"
+" once they are reloaded. This option does not clear any private information "
+"or unlink your activity, nor does it affect your current connections to "
+"other websites."
+msgstr ""
+"Det här alternativet är användbart om <link xref=\"about-tor-browser#how-"
+"tor-works\">utgångsrelän</link> du använder inte kan ansluta till "
+"webbplatsen du begär, eller den laddas inte ordentligt. Om du väljer det "
+"kommer den aktuella aktiva fliken eller fönstret att laddas om över en ny "
+"Tor-krets. Andra öppna flikar och fönster från samma webbplats kommer även "
+"att använda den nya kretsen när de laddas om. Det här alternativet rensar "
+"inte någon privat information eller kopplar bort din aktivitet, och det "
+"påverkar inte dina aktuella anslutningar till andra webbplatser."
+
+#: onionsites.page:6
+msgid "Services that are only accessible using Tor"
+msgstr "Tjänster som endast nås via Tor"
+
+#: onionsites.page:10
+msgid "Onion Services"
+msgstr "Onion tjänster"
+
+#: onionsites.page:11
+msgid ""
+"Onion services (formerly known as “hidden services”) are services (like "
+"websites) that are only accessible through the Tor network."
+msgstr ""
+"Onion tjänster (innan känt som \"gömda tjänster) är tjänster (t.ex "
+"webbplatser) som endast är synliga via Tor nätverket"
+
+#: onionsites.page:16
+msgid ""
+"Onion services offer several advantages over ordinary services on the non-"
+"private web:"
+msgstr ""
+"Onion tjänster har fler fördelar över vanliga tjänster för den icke privata "
+"webben."
+
+#: onionsites.page:23
+msgid ""
+"An onion services’s location and IP address are hidden, making it difficult "
+"for adversaries to censor it or identify its operators."
+msgstr ""
+"En Onions användares plats och IP adress är gömd, vilket gör det svårt för "
+"motståndare att censurera den eller identifiera användaren."
+
+#: onionsites.page:29
+msgid ""
+"All traffic between Tor users and onion services is end-to-end encrypted, so"
+" you do not need to worry about <link xref=\"secure-connections\">connecting"
+" over HTTPS</link>."
+msgstr ""
+"All trafik mellan Tor användaren och Onions tjänster är end-to-end "
+"krypterat, så du behöver inte oroa dig över <link xref=\"secure-"
+"connections\"> förbinder över HTTPS </link>."
+
+#: onionsites.page:36
+msgid ""
+"The address of an onion service is automatically generated, so the operators"
+" do not need to purchase a domain name; the .onion URL also helps Tor ensure"
+" that it is connecting to the right location and that the connection is not "
+"being tampered with."
+msgstr ""
+"Adressen för en Onion tjänst genereras automatisk, användaren behöver inte "
+"köpa ett domän namn; .onion URL som hjälper Tor säkerställa att förbindelsen"
+" är till rätt plats och att anslutningen inte blir manipuleras."
+
+#: onionsites.page:46
+msgid "How to access an onion service"
+msgstr "Hur du kan komma åt en onion tjänst"
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: onionsites.page:48
+msgctxt "_"
+msgid ""
+"external ref='media/onionsites/onion_url.png' "
+"md5='f97f7fe10f07c3959c4430934974bbaa'"
+msgstr ""
+"external ref='media/onionsites/onion_url.png' "
+"md5='f97f7fe10f07c3959c4430934974bbaa'"
+
+#: onionsites.page:50
+msgid ""
+"Just like any other website, you will need to know the address of an onion "
+"service in order to connect to it. An onion address is a string of sixteen "
+"mostly random letters and numbers, followed by “.onion”."
+msgstr ""
+"Precis som vilken annan webbplats behöver du veta adressen till en onion "
+"tjänst för att kunna ansluta dig till den. En Onion adress är en sträng med "
+"sexton slumpmässigt valda bokstäver och nummer följt av .onion."
+
+#: onionsites.page:58 troubleshooting.page:10
+msgid "Troubleshooting"
+msgstr "Felsökning"
+
+#: onionsites.page:59
+msgid ""
+"If you cannot reach the onion service you require, make sure that you have "
+"entered the 16-character onion address correctly: even a small mistake will "
+"stop Tor Browser from being able to reach the site."
+msgstr ""
+"Ifall du inte kan nå Onion tjänsten du vill, dubbel kolla att de 16 tecken i"
+" onion adressen stämmer. Även ett lite misstag kan stoppa Tor webbläsaren "
+"från att kunna nå sidan."
+
+#: onionsites.page:64
+msgid ""
+"If you are still unable to connect to the onion service, please try again "
+"later. There may be a temporary connection issue, or the site operators may "
+"have allowed it to go offline without warning."
+msgstr ""
+"Om du fortfarande inte kan ansluta till Onion tjänsten, var god att försök "
+"senare. Det kan finnas tillfälliga anslutnings problem, eller har en sid "
+"operatör låtit den gå offline utan att ge en förvarning. "
+
+#: onionsites.page:69
+msgid ""
+"You can also ensure that you're able to access other onion services by "
+"connecting to <link href=\"http://3g2upl4pq6kufc4m.onion/\">DuckDuckGo's "
+"Onion Service</link>"
+msgstr ""
+"Du kan också se till att du har tillgång till andra onion-tjänster genom att"
+" ansluta till <link href=\"http://3g2upl4pq6kufc4m.onion/\">DuckDuckGo's "
+"Onion Service</link>"
+
+#: plugins.page:6
+msgid "How Tor Browser handles add-ons, plugins and JavaScript"
+msgstr "Hur Tor Browser hanterar add-ons, pluginsoch JavaScript"
+
+#: plugins.page:10
+msgid "Plugins, add-ons and JavaScript"
+msgstr "Plugins, add-ons och JavaScript"
+
+#: plugins.page:13
+msgid "Flash Player"
+msgstr "Flash Player"
+
+#: plugins.page:14
+msgid ""
+"Video websites, such as Vimeo make use of the Flash Player plugin to display"
+" video content. Unfortunately, this software operates independently of Tor "
+"Browser and cannot easily be made to obey Tor Browser’s proxy settings. It "
+"can therefore reveal your real location and IP address to the website "
+"operators, or to an outside observer. For this reason, Flash is disabled by "
+"default in Tor Browser, and enabling it is not recommended."
+msgstr ""
+"Video webbplatser, som Vimeo, använder sig av Flash Player för att kunna "
+"spela upp video innehållet. Tyvärr verkar detta programmet utanför Tor "
+"webbläsaren och det går inte att få det att lätt uppnå Tor webbläsarens "
+"proxy inställningar. Flash player kan därför visa din riktiga position och "
+"IP-adress till webbplatsens operatör eller andra observatörer. På grund av "
+"detta är Flash avstängt från början i Tor webbläsaren, men det går att slå "
+"på den fast det rekomenderas inte."
+
+#: plugins.page:23
+msgid ""
+"Some video websites (such as YouTube) offer alternative video delivery "
+"methods that do not use Flash. These methods may be compatible with Tor "
+"Browser."
+msgstr ""
+"En del video webbplatser (som Youtube) erbjuder andra alternativ för att "
+"kunna spela upp video innehållet som inte använder sig av Flash. Dessa "
+"alternativen kan vara kompatibla med Tor webbläsaren."
+
+#: plugins.page:31
+msgid "JavaScript"
+msgstr "JavaScript"
+
+#: plugins.page:32
+msgid ""
+"JavaScript is a programming language that websites use to offer interactive "
+"elements such as video, animation, audio, and status timelines. "
+"Unfortunately, JavaScript can also enable attacks on the security of the "
+"browser, which might lead to deanonymization."
+msgstr ""
+"JavaScript är ett programerings språk som används av webbplatser för att "
+"skapa interaktiva delar som video, animationer, ljud och status tidslinjer. "
+"Javascrupt kan tyvärr också göra det möjligt för attacker på webbläsarens "
+"säkerhet, vilket kan leda till att du inte är anonym längre. "
+
+#: plugins.page:39
+msgid ""
+"Tor Browser includes an add-on called NoScript, accessed through the “S” "
+"icon at the top-left of the window, which allows you to control the "
+"JavaScript that runs on individual web pages, or to block it entirely."
+msgstr ""
+"Tor webbläsaren inkluderar ett plug-in som heter NoScript, tillgängligt via "
+"\"S\" ikonen högst upp i fönstrets vänstra hörnan, vilket gör det möjligt "
+"för dig att kontrollera den JavaScript som körs på inviduella webbplatser "
+"eller att blocker allt helt. "
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: plugins.page:45
+msgctxt "_"
+msgid ""
+"external ref='media/plugins/noscript_menu.png' "
+"md5='df9e684b76a3c2e2bdcb879a19c20471'"
+msgstr ""
+"external ref='media/plugins/noscript_menu.png' "
+"md5='df9e684b76a3c2e2bdcb879a19c20471'"
+
+#: plugins.page:47
+msgid ""
+"Users who require a high degree of security in their web browsing should set"
+" Tor Browser’s <link xref=\"security-slider\">Security Slider</link> to "
+"“Medium-High” (which disables JavaScript for non-HTTPS websites) or “High” "
+"(which does so for all websites). However, disabling JavaScript will prevent"
+" many websites from displaying correctly, so Tor Browser’s default setting "
+"is to allow all websites to run scripts."
+msgstr ""
+"Användare som behöver en hög grad av säkerhet i sin webbläsning bör ställa "
+"in Tor Browsers <link xref=\"security-slider\">Säkerhetsreglage</link> till "
+"\"Medel-Hög\" (som inaktiverar JavaScript för webbplatser utan HTTPS) eller "
+"\"Hög\" (vilket gör det för alla webbplatser). Om du inaktiverar JavaScript "
+"kommer det dock att hindra att många webbplatser visas korrekt, så Tor "
+"Browsers standardinställning tillåter alla webbplatser att köra skript."
+
+#: plugins.page:58
+msgid "Browser Add-ons"
+msgstr "Add-ons till webläsaren"
+
+#: plugins.page:59
+msgid ""
+"Tor Browser is based on Firefox, and any browser add-ons or themes that are "
+"compatible with Firefox can also be installed in Tor Browser."
+msgstr ""
+"Tor Browser är baserad på Firefox, och alla webbläsartillägg eller teman som"
+" är kompatibla med Firefox kan också installeras i Tor Browser."
+
+#: plugins.page:64
+msgid ""
+"However, the only add-ons that have been tested for use with Tor Browser are"
+" those included by default. Installing any other browser add-ons may break "
+"functionality in Tor Browser or cause more serious problems that affect your"
+" privacy and security. It is strongly discouraged to install additional add-"
+"ons, and the Tor Project will not offer support for these configurations."
+msgstr ""
+"Men de enda tillägg som har testats för användning med Tor Browser är de som"
+" ingår som standard. Installera andra tilläggsprogram för webbläsare kan "
+"bryta funktionen i Tor Browser eller orsaka allvarligare problem som "
+"påverkar din integritet och säkerhet. Det är starkt avskräckt att installera"
+" ytterligare tillägg, och Tor Project erbjuder inte stöd för dessa "
+"konfigurationer."
+
+#: secure-connections.page:8
+msgid "Learn how to protect your data using Tor Browser and HTTPS"
+msgstr "Lär hur du skyddar din data med hjälp av Tor Browser och HTTPS"
+
+#: secure-connections.page:12
+msgid "Secure Connections"
+msgstr "Säkra anslutningar"
+
+#: secure-connections.page:14
+msgid ""
+"If personal information such as a login password travels unencrypted over "
+"the Internet, it can very easily be intercepted by an eavesdropper. If you "
+"are logging into any website, you should make sure that the site offers "
+"HTTPS encryption, which protects against this kind of eavesdropping. You can"
+" verify this in the URL bar: if your connection is encrypted, the address "
+"will begin with “https://”, rather than “http://”."
+msgstr ""
+"Om personuppgifter, t.ex. ett inloggningslösenord, körs okrypterat via "
+"Internet, kan det mycket enkelt avlyssas av en tjuvlyssnare. Om du loggar in"
+" på någon webbplats bör du se till att webbplatsen erbjuder HTTPS-"
+"kryptering, vilket skyddar mot denna typ av avlyssning. Du kan verifiera "
+"detta i adressfältet: Om din anslutning är krypterad börjar adressen med "
+"\"https://\", snarare än \"http://\"."
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: secure-connections.page:24
+msgctxt "_"
+msgid ""
+"external ref='media/secure-connections/https.png' "
+"md5='364bcbde7a649b0cea9ae178007c1a50'"
+msgstr ""
+"external ref='media/secure-connections/https.png' "
+"md5='364bcbde7a649b0cea9ae178007c1a50'"
+
+#: secure-connections.page:26
+msgid ""
+"The following visualization shows what information is visible to "
+"eavesdroppers with and without Tor Browser and HTTPS encryption:"
+msgstr ""
+"Följande visualisering visar vilken information som är synlig för "
+"tjuvlyssnare med och utan Tor Browser och HTTPS-kryptering:"
+
+#: secure-connections.page:35
+msgid ""
+"Click the “Tor” button to see what data is visible to observers when you're "
+"using Tor. The button will turn green to indicate that Tor is on."
+msgstr ""
+"Klicka på \"Tor\"-knappen för att se vilka data som är synliga för "
+"observatörer när du använder Tor. Knappen blir grön för att indikera att Tor"
+" är på."
+
+#: secure-connections.page:42
+msgid ""
+"Click the “HTTPS” button to see what data is visible to observers when "
+"you're using HTTPS. The button will turn green to indicate that HTTPS is on."
+msgstr ""
+"Klicka på knappen \"HTTPS\" för att se vilken data som är synlig för "
+"observatörer när du använder HTTPS. Knappen blir grön för att indikera att "
+"HTTPS är på."
+
+#: secure-connections.page:49
+msgid ""
+"When both buttons are green, you see the data that is visible to observers "
+"when you are using both tools."
+msgstr ""
+"När båda knapparna är gröna, ser du de data som är synliga för observatörer "
+"när du använder båda verktygen."
+
+#: secure-connections.page:55
+msgid ""
+"When both buttons are grey, you see the data that is visible to observers "
+"when you don't use either tool."
+msgstr ""
+"När båda knapparna är grå, ser du de data som är synliga för observatörer "
+"när du inte använder något av dessa verktyg."
+
+#: secure-connections.page:62
+msgid "Potentially visible data"
+msgstr "Potentiellt synliga data"
+
+#: secure-connections.page:70
+msgid "The site being visited."
+msgstr "Webbplatsen som besöks."
+
+#: secure-connections.page:81
+msgid "Username and password used for authentication."
+msgstr "Användarnamn och lösenord som används för autentisering"
+
+#: secure-connections.page:92
+msgid "Data being transmitted."
+msgstr "Data överförs"
+
+#: secure-connections.page:103
+msgid ""
+"Network location of the computer used to visit the website (the public IP "
+"address)."
+msgstr ""
+"Nätverksplats på datorn som används för att besöka webbplatsen (den publika "
+"IP-adress)."
+
+#: secure-connections.page:115
+msgid "Whether or not Tor is being used."
+msgstr "Om Tor används eller ej"
+
+#: security-slider.page:6
+msgid "Configuring Tor Browser for security and usability"
+msgstr "Konfigurera Tor Browser för säkerhet och användbarhet"
+
+#: security-slider.page:10
+msgid "Security Slider"
+msgstr "Säkerhetsreglage"
+
+#: security-slider.page:11
+msgid ""
+"Tor Browser includes a “Security Slider” that lets you increase your "
+"security by disabling certain web features that can be used to attack your "
+"security and anonymity. Increasing Tor Browser’s security level will stop "
+"some web pages from functioning properly, so you should weigh your security "
+"needs against the degree of usability you require."
+msgstr ""
+"Tor Browser innehåller en \"Säkerhetsreglage\" som låter dig öka säkerheten "
+"genom att inaktivera vissa webbfunktioner som kan användas för att attackera"
+" din säkerhet och anonymitet. Ökande av Tor Browserens säkerhetsnivå hindrar"
+" vissa webbplatser från att fungera korrekt, så du borde väga dina "
+"säkerhetsbehov mot den grad av användbarhet du behöver."
+
+#: security-slider.page:21
+msgid "Accessing the Security Slider"
+msgstr "Åtkomst till säkerhetsreglaget"
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: security-slider.page:23
+msgctxt "_"
+msgid ""
+"external ref='media/security-slider/slider.png' "
+"md5='3c469cd3ed9f60ebb6bbbc63daa90082'"
+msgstr ""
+"external ref='media/security-slider/slider.png' "
+"md5='3c469cd3ed9f60ebb6bbbc63daa90082'"
+
+#: security-slider.page:25
+msgid ""
+"The Security Slider is located in Torbutton’s “Privacy and Security "
+"Settings” menu."
+msgstr ""
+"Säkerhetsreglaget finns i Torbuttons \"Sekretess och "
+"säkerhetsinställningar\"-meny."
+
+#: security-slider.page:32
+msgid "Security Levels"
+msgstr "Säkerhetsnivåer"
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: security-slider.page:34
+msgctxt "_"
+msgid ""
+"external ref='media/security-slider/slider_window.png' "
+"md5='c733bdccd1731ed1a772777b25bae7a1'"
+msgstr ""
+"external ref='media/security-slider/slider_window.png' "
+"md5='c733bdccd1731ed1a772777b25bae7a1'"
+
+#: security-slider.page:36
+msgid ""
+"Increasing the level of the Security Slider will disable or partially "
+"disable certain browser features to protect against possible attacks."
+msgstr ""
+"Om du höjer nivån på säkerhetsreglaget kommer du att inaktivera eller delvis"
+" inaktivera vissa webbläsarfunktioner för att skydda mot eventuella "
+"attacker."
+
+#: security-slider.page:42
+msgid "High"
+msgstr "Hög"
+
+#: security-slider.page:43
+msgid ""
+"At this level, HTML5 video and audio media become click-to-play via "
+"NoScript; all JavaScript performance optimizations are disabled; some "
+"mathematical equations may not display properly; some font rendering "
+"features are disabled; some types of image are disabled; Javascript is "
+"disabled by default on all sites; most video and audio formats are disabled;"
+" and some fonts and icons may not display correctly."
+msgstr ""
+"På den här nivån blir HTML5-video och ljudmedia klicka-för-att-spela via "
+"NoScript; alla JavaScript-prestandaoptimeringar är inaktiverade; vissa "
+"matematiska ekvationer kanske inte visas korrekt; vissa typsnittsfunktioner "
+"är inaktiverade; vissa typer av bilder är inaktiverade; Javascript är "
+"inaktiverat som standard på alla webbplatser; De flesta video- och "
+"ljudformat är inaktiverade; och vissa typsnitt och ikoner kanske inte visas "
+"korrekt."
+
+#: security-slider.page:53
+msgid "Medium-High"
+msgstr "Medium-hög"
+
+#: security-slider.page:54
+msgid ""
+"At this level, HTML5 video and audio media become click-to-play via "
+"NoScript; all JavaScript performance optimizations are disabled; some "
+"mathematical equations may not display properly; some font rendering "
+"features are disabled; some types of image are disabled; and JavaScript is "
+"disabled by default on all non-<link xref=\"secure-"
+"connections\">HTTPS</link> sites."
+msgstr ""
+"På den här nivån blir HTML5-video och ljudmedia klicka-för-att-spela via "
+"NoScript; alla JavaScript-prestandaoptimeringar är inaktiverade; vissa "
+"matematiska ekvationer kanske inte visas korrekt; vissa typsnittsfunktioner "
+"är inaktiverade; vissa typer av bilder är inaktiverade; Javascript är "
+"inaktiverat som standard på alla webbplatser; De flesta video- och "
+"ljudformat är inaktiverade; och vissa typsnitt och ikoner kanske inte visas "
+"korrekt på alla <link xref=\"secure-connections\">HTTPS</link>-sidor."
+
+#: security-slider.page:64
+msgid "Medium-Low"
+msgstr "Medium-låg"
+
+#: security-slider.page:65
+msgid ""
+"At this level, HTML5 video and audio media become click-to-play via "
+"NoScript; some <link xref=\"plugins\">JavaScript</link> performance "
+"optimizations are disabled, causing some websites to run more slowly; and "
+"some mathematical equations may not display properly."
+msgstr ""
+"På den här nivån blir HTML5-video och ljudmedia klicka-för-att-spela via "
+"NoScript; vissa <link xref=\"plugins\">JavaScript</link> "
+"prestandaoptimeringar är inaktiverade, vilket gör att vissa webbplatser körs"
+" långsammare; och vissa matematiska ekvationer kanske inte visas korrekt."
+
+#: security-slider.page:73
+msgid "Low"
+msgstr "Låg"
+
+#: security-slider.page:74
+msgid ""
+"At this level, all browser features are enabled. This is the most usable "
+"option."
+msgstr ""
+"På den här säkerhetsnivån är webbläsarens alla funktioner aktiverade. Detta "
+"är det mest användbara alternativet. "
+
+#: transports.page:6 transports.page:20
+msgid "Types of pluggable transport"
+msgstr "Typer av pluggbara transporter"
+
+#: transports.page:10
+msgid "Pluggable Transports"
+msgstr "Pluggbara transporter"
+
+#: transports.page:12
+msgid ""
+"Pluggable transports are tools that Tor can use to disguise the traffic it "
+"sends out. This can be useful in situations where an Internet Service "
+"Provider or other authority is actively blocking connections to the Tor "
+"network."
+msgstr ""
+"Pluggbara transporter är verktyg som Tor kan använda för att dölja den "
+"trafik som den skickar ut. Detta kan vara användbart i situationer där en "
+"Internetleverantör eller annan myndighet aktivt blockerar anslutningar till "
+"Tor-nätverket."
+
+#: transports.page:21
+msgid ""
+"Currently there are six pluggable transports available, but more are being "
+"developed."
+msgstr ""
+"För närvarande finns sex pluggbara transporter tillgängliga, men fler "
+"utvecklas."
+
+#: transports.page:28
+msgid "obfs3"
+msgstr "obfs3"
+
+#: transports.page:33
+msgid ""
+"obfs3 makes Tor traffic look random, so that it does not look like Tor or "
+"any other protocol. obfs3 bridges will work in most places."
+msgstr ""
+"obfs3 gör att Tor-trafiken ser slumpmässig ut, så att den inte ser ut som "
+"Tor eller något annat protokoll. obfs3-broar kommer att fungera på de flesta"
+" platser."
+
+#: transports.page:42
+msgid "obfs4"
+msgstr "obfs4"
+
+#: transports.page:47
+msgid ""
+"obfs4 makes Tor traffic look random like obfs3, and also prevents censors "
+"from finding bridges by Internet scanning. obfs4 bridges are less likely to "
+"be blocked than obfs3 bridges."
+msgstr ""
+"obfs4 gör att Tor-trafiken ser slumpmässigt ut som obfs3, och hindrar också "
+"censorer från att hitta broar via Internet-skanning. obfs4-bryggor är mindre"
+" benägna att blockeras än obfs3-broar."
+
+#: transports.page:56
+msgid "Scramblesuit"
+msgstr "Scramblesuit"
+
+#: transports.page:61
+msgid "ScrambleSuit is similar to obfs4 but has a different set of bridges."
+msgstr "ScrambleSuit liknar obfs4 men har en annan uppsättning av bryggor."
+
+#: transports.page:69
+msgid "FTE"
+msgstr "FTE"
+
+#: transports.page:74
+msgid ""
+"FTE (format-transforming encryption) disguises Tor traffic as ordinary web "
+"(HTTP) traffic."
+msgstr ""
+"FTE (format-omvandlingskryptering) döljer Tor-trafik som vanlig webb (HTTP) "
+"trafik."
+
+#: transports.page:82
+msgid "meek"
+msgstr "meek"
+
+#: transports.page:87
+msgid ""
+"These transports all make it look like you are browsing a major web site "
+"instead of using Tor. meek-amazon makes it look like you are using Amazon "
+"Web Services; meek-azure makes it look like you are using a Microsoft web "
+"site; and meek-google makes it look like you are using Google search."
+msgstr ""
+"Dessa transporter gör att det ser ut som om du surfar på en större webbplats"
+" istället för att använda Tor. meek-amazon gör att det ser ut som om du "
+"använder Amazon Web Services; meek azure gör att det ser ut som om du "
+"använder en Microsoft-webbplats. och meek-google gör att det ser ut som om "
+"du använder Google-sökning."
+
+#: troubleshooting.page:6
+msgid "What to do if Tor Browser doesn’t work"
+msgstr "Vad du kan göra om Tor webbläsare inte fungerar"
+
+#: troubleshooting.page:12
+msgid ""
+"You should be able to start browsing the web using Tor Browser shortly after"
+" running the program, and clicking the “Connect” button if you are using it "
+"for the first time."
+msgstr ""
+"Du bör kunna börja surfa på webben med Tor Browser snart efter att du kör "
+"programmet och klickar på \"Anslut\"-knappen om du använder den för första "
+"gången."
+
+#: troubleshooting.page:21
+msgid "Quick fixes"
+msgstr "Snabba åtgärder"
+
+#: troubleshooting.page:22
+msgid ""
+"If Tor Browser doesn’t connect, there may be a simple solution. Try each of "
+"the following:"
+msgstr ""
+"Om Tor webbläsare inte ansluter, kan det finnas en enkel lösning. Prova "
+"följande alternativ:"
+
+#: troubleshooting.page:29
+msgid ""
+"Your computer’s system clock must be set correctly, or Tor will not be able "
+"to connect."
+msgstr ""
+"Datorns klocka måste vara korrekt inställd, annars kan Tor inte ansluta."
+
+#: troubleshooting.page:35
+msgid ""
+"Make sure another Tor Browser is not already running. If you’re not sure if "
+"Tor Browser is running, restart your computer."
+msgstr ""
+"Se till att en annan Tor Browser inte redan körs. Om du inte är säker på om "
+"Tor Browser körs startar du om datorn."
+
+#: troubleshooting.page:41
+msgid ""
+"Make sure that any antivirus program you have installed is not preventing "
+"Tor from running. You may need to consult the documentation for your "
+"antivirus software if you do not know how to do this."
+msgstr ""
+"Se till att alla antivirusprogram du har installerat inte hindrar Tor från "
+"att köras. Du kan behöva konsultera dokumentationen för ditt "
+"antivirusprogram om du inte vet hur du gör det här."
+
+#: troubleshooting.page:49
+msgid "Temporarily disable your firewall."
+msgstr "Stäng av din brandvägg tillfälligt"
+
+#: troubleshooting.page:54
+msgid ""
+"Delete Tor Browser and install it again. If updating, do not just overwrite "
+"your previous Tor Browser files; ensure they are fully deleted beforehand."
+msgstr ""
+"Ta bort Tor Browser och installera den igen. Om du uppdaterar, skriv inte "
+"bara över dina tidigare Tor Browser-filer; se till att de helt raderas i "
+"förväg."
+
+#: troubleshooting.page:64
+msgid "Is your connection censored?"
+msgstr "Är din anslutning censurerad?"
+
+#: troubleshooting.page:65
+msgid ""
+"If you still can’t connect, your Internet Service Provider might be "
+"censoring connections to the Tor network. Read the <link "
+"xref=\"circumvention\">Circumvention</link> section for possible solutions."
+msgstr ""
+"Om du fortfarande inte kan ansluta kan din Internetleverantör censurera "
+"anslutningar till Tor-nätverket. Läs avsnittet <link "
+"xref=\"circumvention\">Kringgående</link> för möjliga lösningar."
+
+#: troubleshooting.page:74
+msgid "Known issues"
+msgstr "Kända problem"
+
+#: troubleshooting.page:75
+msgid ""
+"Tor Browser is under constant development, and some issues are known about "
+"but not yet fixed. Please check the <link xref=\"known-issues\">Known "
+"Issues</link> page to see if the problem you are experiencing is already "
+"listed there."
+msgstr ""
+"Tor Browser är under konstant utveckling, och vissa problem är kända men "
+"ännu inte fastställda. Kontrollera sidan med <link xref=\"known-"
+"issues\">kända problem</link> för att se om problemet du upplever är redan "
+"listat där."
+
+#: uninstalling.page:6
+msgid "How to remove Tor Browser from your system"
+msgstr "Hur du raderar Tor webbläsare från ditt system"
+
+#: uninstalling.page:10
+msgid "Uninstalling"
+msgstr "Avinstallera"
+
+#: uninstalling.page:12
+msgid ""
+"Tor Browser does not affect any of the existing software or settings on your"
+" computer. Uninstalling Tor Browser will not affect your system’s software "
+"or settings."
+msgstr ""
+"Tor Browser påverkar inte någon av befintlig programvara eller inställningar"
+" på din dator. Avinstallation av Tor Browser påverkar inte ditt systems "
+"program eller inställningar."
+
+#: uninstalling.page:18
+msgid "Removing Tor Browser from your system is simple:"
+msgstr "Att radera Tor från ditt system är enkelt:"
+
+#: uninstalling.page:24
+msgid ""
+"Locate your Tor Browser folder. The default location on Windows is the "
+"Desktop; on Mac OS X it is the Applications folder. On Linux, there is no "
+"default location, however the folder will be named \"tor-browser_en-US\" if "
+"you are running the English Tor Browser."
+msgstr ""
+"Leta reda på din Tor Browser-mapp. Standardplatsen i Windows är skrivbordet;"
+" På Mac OS X är det mappen Program. På Linux finns ingen standardplats, men "
+"mappen kommer att benämnas \"tor-browser_en-US\" om du kör den engelska Tor "
+"Browser."
+
+#: uninstalling.page:32
+msgid "Delete the Tor Browser folder."
+msgstr "Radera Tor mappen"
+
+#: uninstalling.page:35
+msgid "Empty your Trash"
+msgstr "Töm din Skräpkorg"
+
+#: uninstalling.page:39
+msgid ""
+"Note that your operating system’s standard “Uninstall” utility is not used."
+msgstr ""
+"Observera att operativsystemets standard \"Avinstallera\"-verktyg inte "
+"används."
+
+#: updating.page:6
+msgid "How to update Tor Browser"
+msgstr "Hur du uppdaterar Tor Webläsare"
+
+#: updating.page:10
+msgid "Updating"
+msgstr "Uppdaterar"
+
+#: updating.page:12
+msgid ""
+"Tor Browser must be kept updated at all times. If you continue to use an "
+"outdated version of the software, you may be vulnerable to serious security "
+"flaws that compromise your privacy and anonymity."
+msgstr ""
+"Tor Browser måste hållas uppdaterad hela tiden. Om du fortsätter att använda"
+" en föråldrad version av programvaran, kan du vara utsatt för allvarliga "
+"säkerhetsbrister som äventyrar din integritet och anonymitet."
+
+#: updating.page:18
+msgid ""
+"Tor Browser will prompt you to update the software once a new version has "
+"been released: the Torbutton icon will display a yellow triangle, and you "
+"may see a written update indicator when Tor Browser opens. You can update "
+"either automatically or manually."
+msgstr ""
+"Tor Browser uppmanar dig att uppdatera programvaran när en ny version har "
+"släppts: Torbutton-ikonen kommer att visa en gul triangel och du kan se en "
+"skriftlig uppdateringsindikator när Tor Browser öppnas. Du kan uppdatera "
+"antingen automatiskt eller manuellt."
+
+#: updating.page:26
+msgid "Updating Tor Browser automatically"
+msgstr "Uppdatera Tor webbläsare automatiskt"
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: updating.page:30
+msgctxt "_"
+msgid ""
+"external ref='media/updating/update1.png' "
+"md5='9ff01eb653d92124746fc31efde2bf07'"
+msgstr ""
+"external ref='media/updating/update1.png' "
+"md5='9ff01eb653d92124746fc31efde2bf07'"
+
+#: updating.page:32
+msgid ""
+"When you are prompted to update Tor Browser, click on the Torbutton icon, "
+"then select “Check for Tor Browser Update”."
+msgstr ""
+"När du uppmanas att uppdatera Tor Browser, klicka på Torbutton-ikonen och "
+"välj sedan \"När du uppmanas att uppdatera Tor Browser, klicka på Torbutton-"
+"ikonen och välj sedan \"Kontrollera efter uppdatering av Tor Browser\"."
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: updating.page:39
+msgctxt "_"
+msgid ""
+"external ref='media/updating/update3.png' "
+"md5='4bd08622b0cacf20b13f75c432176ed3'"
+msgstr ""
+"external ref='media/updating/update3.png' "
+"md5='4bd08622b0cacf20b13f75c432176ed3'"
+
+#: updating.page:41
+msgid ""
+"When Tor Browser has finished checking for updates, click on the “Update” "
+"button."
+msgstr ""
+"När Tor webbläsare har granskat om tillgängliga uppdateringar finns, klicka "
+"på knappen \"Uppdatera\"."
+
+#. This is a reference to an external file such as an image or video. When
+#. the file changes, the md5 hash will change to let you know you need to
+#. update your localized copy. The msgstr is not used at all. Set it to
+#. whatever you like once you have updated your copy of the file.
+#: updating.page:48
+msgctxt "_"
+msgid ""
+"external ref='media/updating/update4.png' "
+"md5='1d795e7b695738531db9d4b2b0fb5313'"
+msgstr ""
+"external ref='media/updating/update4.png' "
+"md5='1d795e7b695738531db9d4b2b0fb5313'"
+
+#: updating.page:50
+msgid ""
+"Wait for the update to download and install, then restart Tor Browser. You "
+"will now be running the latest version."
+msgstr ""
+"Vänta på att uppdateringen ska hämtas och installeras, starta sedan om Tor "
+"Browser. Du kommer nu att köra den senaste versionen."
+
+#: updating.page:58
+msgid "Updating Tor Browser manually"
+msgstr "Uppdatera Tor webbläsaren manuellt"
+
+#: updating.page:61
+msgid ""
+"When you are prompted to update Tor Browser, finish the browsing session and"
+" close the program."
+msgstr ""
+"När du uppmanas att uppdatera Tor Browser, avsluta webbläsningssessionen och"
+" stäng programmet."
+
+#: updating.page:67
+msgid ""
+"Remove Tor Browser from your system by deleting the folder that contains it "
+"(see the <link xref=\"uninstalling\">Uninstalling</link> section for more "
+"information)."
+msgstr ""
+"Ta bort Tor Browser från ditt system genom att radera mappen som innehåller "
+"den (se avsnittet <link xref=\"uninstalling\">Avinstallera</link> för mer "
+"information)."
+
+#: updating.page:74
+msgid ""
+"Visit <link href=\"https://www.torproject.org/projects/torbrowser.html.en\">"
+" https://www.torproject.org/projects/torbrowser.html.en</link> and download "
+"a copy of the latest Tor Browser release, then install it as before."
+msgstr ""
+"Besök <link href=\"https://www.torproject.org/projects/torbrowser.html.en\">"
+" https://www.torproject.org/projects/torbrowser.html.en</link> och ladda ner"
+" en kopia av den senaste Tor Browser utgåvan, installera den sedan som "
+"förut."
1
0

[translation/tor-browser-manual] Update translations for tor-browser-manual
by translation@torproject.org 01 Feb '18
by translation@torproject.org 01 Feb '18
01 Feb '18
commit ecfab7614490f30bc252e3750aadff6b9494d22b
Author: Translation commit bot <translation(a)torproject.org>
Date: Thu Feb 1 20:20:31 2018 +0000
Update translations for tor-browser-manual
---
sv/sv.po | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/sv/sv.po b/sv/sv.po
index b33d863bb..1b0d391b4 100644
--- a/sv/sv.po
+++ b/sv/sv.po
@@ -1632,6 +1632,10 @@ msgid ""
"Issues</link> page to see if the problem you are experiencing is already "
"listed there."
msgstr ""
+"Tor Browser är under konstant utveckling, och vissa problem är kända men "
+"ännu inte fastställda. Kontrollera sidan med <link xref=\"known-"
+"issues\">kända problem</link> för att se om problemet du upplever är redan "
+"listat där."
#: uninstalling.page:6
msgid "How to remove Tor Browser from your system"
@@ -1647,6 +1651,9 @@ msgid ""
" computer. Uninstalling Tor Browser will not affect your system’s software "
"or settings."
msgstr ""
+"Tor Browser påverkar inte någon av befintlig programvara eller inställningar"
+" på din dator. Avinstallation av Tor Browser påverkar inte ditt systems "
+"program eller inställningar."
#: uninstalling.page:18
msgid "Removing Tor Browser from your system is simple:"
@@ -1659,6 +1666,10 @@ msgid ""
"default location, however the folder will be named \"tor-browser_en-US\" if "
"you are running the English Tor Browser."
msgstr ""
+"Leta reda på din Tor Browser-mapp. Standardplatsen i Windows är skrivbordet;"
+" På Mac OS X är det mappen Program. På Linux finns ingen standardplats, men "
+"mappen kommer att benämnas \"tor-browser_en-US\" om du kör den engelska Tor "
+"Browser."
#: uninstalling.page:32
msgid "Delete the Tor Browser folder."
@@ -1689,6 +1700,9 @@ msgid ""
"outdated version of the software, you may be vulnerable to serious security "
"flaws that compromise your privacy and anonymity."
msgstr ""
+"Tor Browser måste hållas uppdaterad hela tiden. Om du fortsätter att använda"
+" en föråldrad version av programvaran, kan du vara utsatt för allvarliga "
+"säkerhetsbrister som äventyrar din integritet och anonymitet."
#: updating.page:18
msgid ""
@@ -1697,6 +1711,10 @@ msgid ""
"may see a written update indicator when Tor Browser opens. You can update "
"either automatically or manually."
msgstr ""
+"Tor Browser uppmanar dig att uppdatera programvaran när en ny version har "
+"släppts: Torbutton-ikonen kommer att visa en gul triangel och du kan se en "
+"skriftlig uppdateringsindikator när Tor Browser öppnas. Du kan uppdatera "
+"antingen automatiskt eller manuellt."
#: updating.page:26
msgid "Updating Tor Browser automatically"
@@ -1720,6 +1738,9 @@ msgid ""
"When you are prompted to update Tor Browser, click on the Torbutton icon, "
"then select “Check for Tor Browser Update”."
msgstr ""
+"När du uppmanas att uppdatera Tor Browser, klicka på Torbutton-ikonen och "
+"välj sedan \"När du uppmanas att uppdatera Tor Browser, klicka på Torbutton-"
+"ikonen och välj sedan \"Kontrollera efter uppdatering av Tor Browser\"."
#. This is a reference to an external file such as an image or video. When
#. the file changes, the md5 hash will change to let you know you need to
@@ -1781,6 +1802,9 @@ msgid ""
"(see the <link xref=\"uninstalling\">Uninstalling</link> section for more "
"information)."
msgstr ""
+"Ta bort Tor Browser från ditt system genom att radera mappen som innehåller "
+"den (se avsnittet <link xref=\"uninstalling\">Avinstallera</link> för mer "
+"information)."
#: updating.page:74
msgid ""
1
0

[tor-browser-spec/master] Typo, grammar, spell check. Also some XXX notes.
by mikeperry@torproject.org 01 Feb '18
by mikeperry@torproject.org 01 Feb '18
01 Feb '18
commit 1fd0569a1c2737adf9d01340ee7a5cabc29b3969
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Wed Jan 31 02:26:32 2018 +0000
Typo, grammar, spell check. Also some XXX notes.
---
design-doc/design.xml | 58 ++++++++++++++++++++++++++++++++-------------------
1 file changed, 37 insertions(+), 21 deletions(-)
diff --git a/design-doc/design.xml b/design-doc/design.xml
index cdab986..43c4cb9 100644
--- a/design-doc/design.xml
+++ b/design-doc/design.xml
@@ -738,7 +738,7 @@ Also, JavaScript can be used to query the user's timezone via the
url="https://www.khronos.org/registry/webgl/specs/1.0/#5.13">WebGL</ulink> can
reveal information about the video card in use, and high precision timing
information can be used to <ulink
-url="https://cseweb.ucsd.edu/~hovav/dist/jspriv.pdf">fingerprint the cpu and
+url="https://cseweb.ucsd.edu/~hovav/dist/jspriv.pdf">fingerprint the CPU and
interpreter speed</ulink>. JavaScript features such as
<ulink url="https://www.w3.org/TR/resource-timing/">Resource Timing</ulink>
may leak an unknown amount of network timing related information. And, moreover,
@@ -1086,7 +1086,7 @@ a helper application.
Furthermore, we ship a <ulink url="https://gitweb.torproject.org/tor-browser.git/commit/?h=tor-browser-52.5.2e…">patch for Linux users</ulink> that makes
sure sftp:// and smb:// URLs are not passed along to the operating system as this
-can lead to proxy bypasses on systems that have GIO/GnomeVS support. And proxy
+can lead to proxy bypasses on systems that have GIO/GnomeVFS support. And proxy
bypass risks due to file:// URLs should be mitigated for macOS and Linux users
by <ulink url="https://gitweb.torproject.org/tor-browser.git/commit/?h=tor-browser-52.5.2e…">
two</ulink> <ulink url="https://gitweb.torproject.org/tor-browser.git/commit/?h=tor-browser-52.5.2e…">
@@ -1095,7 +1095,7 @@ further patches</ulink>.
</para>
<para>
-Additionally, modern desktops now pre-emptively fetch any URLs in Drag and
+Additionally, modern desktops now preemptively fetch any URLs in Drag and
Drop events as soon as the drag is initiated. This download happens
independent of the browser's Tor settings, and can be triggered by something
as simple as holding the mouse button down for slightly too long while
@@ -1264,7 +1264,7 @@ and no other browser vendor or standards body had invested the effort to
enumerate or otherwise deal with these vectors for third party tracking. As
such, we have had to enumerate and isolate these identifier sources on a
piecemeal basis. This has gotten better lately with Mozilla stepping up and
-helping us with uplifting our patches, and with contributing own ones where we
+helping us with uplifting our patches, and with contributing their own patches where we
lacked proper fixes. However, we are not done yet with our unlinkability defense
as new identifier sources are still getting added to the web platform. Here is
the list that we have discovered and dealt with to date:
@@ -1303,10 +1303,11 @@ We isolate the content and image cache to the URL bar domain by setting
<para>
Furthermore there is the Cache API (CacheStorage). That one is currently not
available in Tor Browser as we do not allow third party cookies and are in
-Private Browsing Mode by default.
+Private Browsing Mode by default. <!-- XXX: Link to Cache API and briefly
+mention why it is disabled in PBM? What about memory-only cache? -->
</para>
<para>
-Finally, we have the asm.js cache. The cache entry of the sript is (among
+Finally, we have the asm.js cache. The cache entry of the script is (among
others things, like type of CPU, build ID, source characters of the asm.js
module etc.) keyed <ulink url="https://blog.mozilla.org/luke/2014/01/14/asm-js-aot-compilation-and-startup…">to the origin of the script</ulink>.
Lacking a good solution for binding it to the URL bar domain instead we decided
@@ -1581,7 +1582,7 @@ We provide the isolation in Tor Browser by setting
<listitem><command>OCSP</command>
<para>
-OCSP requests go to Certfication Authorities (CAs) to check for revoked
+OCSP requests go to Certificate Authorities (CAs) to check for revoked
certificates. They are sent once the browser is visiting a website via HTTPS and
no cached results are available. Thus, to avoid information leaks, e.g. to exit
relays, OCSP requests MUST go over the same circuit as the HTTPS request causing
@@ -1600,7 +1601,7 @@ the browser itself (similar to the OCSP mechanism mentioned in the previous
section). Those requests MUST be isolated to the URL bar domain.
</para>
- <para><command>Implemetation Status:</command>
+ <para><command>Implementation Status:</command>
Favicon requests are isolated to the URL bar domain by setting
<command>privacy.firstparty.isolate</command> to <command>true</command>.
@@ -1665,7 +1666,7 @@ We allow these requests to proceed, but we isolate them.
The Permissions API allows a website to query the status of different
permissions. Although permissions are keyed to the origin, that is not enough to
-alleviate cross-linkabilility concerns: the combined permission state could work
+alleviate cross-linkability concerns: the combined permission state could work
like an identifier given more and more permissions and their state being
accessible under this API.
@@ -1831,6 +1832,8 @@ population is largely useless for evaluating either attacks or defenses.
Unfortunately, this includes popular large-scale studies such as <ulink
url="https://panopticlick.eff.org/">Panopticlick</ulink> and <ulink
url="https://amiunique.org/">Am I Unique</ulink>.
+<!-- XXX: What about our fpcentral implementation? Is it ready to be mentioned
+here? -->
</para>
</listitem>
@@ -1951,6 +1954,8 @@ url="https://panopticlick.eff.org/">Panopticlick</ulink> or <ulink
url="https://amiunique.org/">Am I Unique</ulink> could report the entropy and
uniqueness rates for all users of a single user agent version, without the
need for complicated statistics about the variance of the measured behaviors.
+<!-- XXX: What about our fpcentral implementation? Is it ready to be mentioned
+here? -->
</para>
<para>
@@ -2237,7 +2242,7 @@ use those fonts exclusively. In addition to that we set the <command>font.name*
is always displayed with the same font. This is not guaranteed even if we bundle
all the fonts Tor Browser uses as it can happen that fonts are loaded in a
different order on different systems. Setting the above mentioned preferences
-works around this issue by specifying the font to use explicitely.
+works around this issue by specifying the font to use explicitly.
</para>
@@ -2412,7 +2417,7 @@ SpeechRecognition (Asynchronous Speech Recognition). The latter is still
disabled in Firefox. However, the former is enabled by default and there is the
risk that <command>speechSynthesis.getVoices()</command> has access to
computer-specific speech packages making them available in an enumerable
-fashion. Morevover, there are callbacks that would allow JavaScript to time how
+fashion. Moreover, there are callbacks that would allow JavaScript to time how
long a phrase takes to be "uttered". To prevent both we set
<command>media.webspeech.synth.enabled</command> to <command>false</command>.
@@ -2430,6 +2435,8 @@ the Touch API by setting <command>dom.w3c_touch_events.enabled</command> to
have this API available we patched the code to give content-window related
coordinates back. Furthermore, we made sure that the touch area described by
<command>Touch.radiusX</command>, <command>Touch.radiusY</command>, and
+<!-- FWIW I suspect that rotationAngle and force will break more things than
+radius, and also reveal less or no persistent information. -->
<command>Touch.rotationAngle</command> does not leak further information and
<command>Touch.force</command> does not reveal how much pressure a user applied
to the surface. That is achieved by a direct
@@ -2452,7 +2459,7 @@ still after that got fixed (and on other platforms where the precision was just
two significant digits anyway) the risk for tracking users remained as combined
with the <command>chargingTime</command> and <command>dischargingTime</command>
the possible values <ulink url="https://senglehardt.com/papers/iwpe17_battery_status_case_study.pdf">
-got estimated to be in the millons</ulink> under normal conditions. We avoid all
+got estimated to be in the millions</ulink> under normal conditions. We avoid all
those possible issues with disabling the Battery Status API by setting
<command>dom.battery.enabled</command> to <command>false</command>.
@@ -2465,6 +2472,9 @@ those possible issues with disabling the Battery Status API by setting
It is possible to get the system uptime of a Tor Browser user by querying the
<command>Event.timestamp</command> property. We avoid this by setting <command>
dom.event.highrestimestamp.enabled</command> to <command>true</command>.
+<!-- XXX: wait, true?? Weren't there other reasons to disable highres
+timestamps? highres DOM timing information was believed to be fingerprintable,
+IIRC. -->
</para>
</listitem>
@@ -2481,6 +2491,10 @@ changed by the keyboard layout nor by the modifier state. On the other hand the
generated by that key. This is dependent on things like keyboard layout, locale
and modifier keys.
+<!-- XXX: We should make some statement about what this does to intl users.
+Also, stuff like this used to be hooked to extensions.torbutton.spoof_english
+if it had user-facing effects -->
+
</para>
<para><command>Design Goal:</command>
@@ -2574,7 +2588,7 @@ and <command>document.timeline.currentTime</command>.
</para>
<para>
-While clamping the clock resolution to 100ms is a step towards neutering the
+While clamping the clock resolution to 100ms is a step towards mitigating
timing-based side channel fingerprinting, it is by no means sufficient. It turns
out that it is possible to subvert our clamping of explicit clocks by using
<ulink url="https://www.usenix.org/system/files/conference/usenixsecurity16/sec16_paper…">
@@ -2610,7 +2624,7 @@ out of a Tor Browser user by deploying resource:// and/or chrome:// URIs. Until
this is fixed in Firefox <ulink url="https://gitweb.torproject.org/torbutton.git/tree/src/components/content-pol…">
we filter</ulink> resource:// and chrome:// requests done
by web content denying them by default. We need a whitelist of resource:// and
-chrome:// URIs, though, to avoid breaking parts of Firefox. Those more than a
+chrome:// URIs, though, to avoid breaking parts of Firefox. There are more than a
dozen Firefox resources do not aid in fingerprinting Tor Browser users as they
are not different on the platforms and in the locales we support.
@@ -2634,7 +2648,7 @@ We set the fallback character set to set to windows-1252 for all locales, via
to instruct the JS engine to use en-US as its internal C locale for all Date,
Math, and exception handling. Additionally, we provide a patch to use an
<ulink url="https://gitweb.torproject.org/tor-browser.git/commit/?h=tor-browser-52.5.2e…">
-en-US label for the <command>isindex</command> HTML element</ulink> instead of
+en-US label for the <command>isindex</command>HTML element</ulink> instead of
letting the label leak the browser's UI locale.
</para>
</listitem>
@@ -2738,8 +2752,9 @@ We clamp keyboard event resolution to 100ms with a <ulink url="https://gitweb.to
<listitem><command>Amount of Processor Cores (hardwareConcurrency)</command>
<para>
-Modern computers have multiple physical processor cores in their CPU available.
-One core typically allows to run more than one thread at a time and
+Modern computers have multiple physical processor cores available in their
+CPU. For optimum performance, native code typically attempts to run as many
+threads as there are cores, and
<command>navigator.hardwareConcurrency</command> makes the number of those
threads (i.e. logical processors) available to web content.
@@ -2754,7 +2769,7 @@ the amount of logical processors available.
We set <command>dom.maxHardwareConcurrency</command> to <command>1</command> to
report the same amount of logical processors for everyone. However, there are
-<ulink url="https://github.com/oftn/core-estimator">probablistic ways of
+<ulink url="https://github.com/oftn/core-estimator">probabilistic ways of
determining the same information available</ulink> which we are not defending
against currently. Moreover, we might even want to think about a more elaborate
approach defending against this fingerprinting technique by not making all users
@@ -2770,7 +2785,7 @@ size exfiltration.
The <ulink url="https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API">
Web Audio API</ulink> provides several means to aid in fingerprinting users.
-At the simplest level it allows differentiating between users having the API
+At the simplest level it allows differentiating between users who have the API
available and those who don't by checking for an <command>AudioContext</command>
or <command>OscillatorNode</command> object. However, there are more bits of
information that the Web Audio API reveals if audio signals generated with an
@@ -2824,6 +2839,7 @@ own needs and preferences. To avoid fingerprintability risks we make Tor Browser
users uniform by setting <command>reader.parse-on-load.enabled</command> to
<command>false</command> and <command>browser.reader.detectedFirstArticle</command>
to <command>true</command>.
+<!-- XXX: Explain how this is fingerprintable -->
</para>
</listitem>
@@ -2837,8 +2853,8 @@ This is often implemented by contacting Mozilla services, be it for displaying
further information about a new feature or by
<ulink url="https://wiki.mozilla.org/Telemetry">sending (aggregated) data back
for analysis</ulink>. While some of those mechanisms are disabled by default on
-release channels (gathering telemetry data comes to mind) others are not. We
-make sure that non of those Mozilla services is contacted to avoid possible
+release channels (such as telemetry data) others are not. We
+make sure that none of those Mozilla services are contacted to avoid possible
fingerprinting risks.
</para>
1
0

01 Feb '18
commit 54783b4c22675925fcfcac77cb95193bc5c32d03
Author: Fernando Fernandez Mancera <ffmancera(a)riseup.net>
Date: Thu Jan 25 20:16:50 2018 +0100
Refactor crypto.[ch] into smaller RSA module.
Add two new files (crypto_rsa.c, crypto_rsa.h) as new module of crypto.[ch].
This new module includes all functions and dependencies related to RSA
operations. Those have been removed from crypto.[ch].
All new changes related to RSA operations must be done in these files.
Follows #24658
Signed-off-by: Fernando Fernandez Mancera <ffmancera(a)riseup.net>
---
src/common/crypto.c | 865 -----------------------------------------------
src/common/crypto.h | 68 +---
src/common/crypto_rsa.c | 878 ++++++++++++++++++++++++++++++++++++++++++++++++
src/common/crypto_rsa.h | 100 ++++++
4 files changed, 980 insertions(+), 931 deletions(-)
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 107b53ad2..bb9820fc2 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -88,13 +88,6 @@ ENABLE_GCC_WARNING(redundant-decls)
/** Largest strong entropy request */
#define MAX_STRONGEST_RAND_SIZE 256
-/** A public key, or a public/private key-pair. */
-struct crypto_pk_t
-{
- int refs; /**< reference count, so we don't have to copy keys */
- RSA *key; /**< The key itself */
-};
-
/** A structure to hold the first half (x, g^x) of a Diffie-Hellman handshake
* while we're waiting for the second.*/
struct crypto_dh_t {
@@ -103,30 +96,6 @@ struct crypto_dh_t {
static int tor_check_dh_key(int severity, const BIGNUM *bn);
-/** Return the number of bytes added by padding method <b>padding</b>.
- */
-static inline int
-crypto_get_rsa_padding_overhead(int padding)
-{
- switch (padding)
- {
- case RSA_PKCS1_OAEP_PADDING: return PKCS1_OAEP_PADDING_OVERHEAD;
- default: tor_assert(0); return -1; // LCOV_EXCL_LINE
- }
-}
-
-/** Given a padding method <b>padding</b>, return the correct OpenSSL constant.
- */
-static inline int
-crypto_get_rsa_padding(int padding)
-{
- switch (padding)
- {
- case PK_PKCS1_OAEP_PADDING: return RSA_PKCS1_OAEP_PADDING;
- default: tor_assert(0); return -1; // LCOV_EXCL_LINE
- }
-}
-
/** Boolean: has OpenSSL's crypto been initialized? */
static int crypto_early_initialized_ = 0;
@@ -363,73 +332,6 @@ crypto_thread_cleanup(void)
#endif
}
-/** used internally: quicly validate a crypto_pk_t object as a private key.
- * Return 1 iff the public key is valid, 0 if obviously invalid.
- */
-static int
-crypto_pk_private_ok(const crypto_pk_t *k)
-{
-#ifdef OPENSSL_1_1_API
- if (!k || !k->key)
- return 0;
-
- const BIGNUM *p, *q;
- RSA_get0_factors(k->key, &p, &q);
- return p != NULL; /* XXX/yawning: Should we check q? */
-#else /* !(defined(OPENSSL_1_1_API)) */
- return k && k->key && k->key->p;
-#endif /* defined(OPENSSL_1_1_API) */
-}
-
-/** used by tortls.c: wrap an RSA* in a crypto_pk_t. */
-crypto_pk_t *
-crypto_new_pk_from_rsa_(RSA *rsa)
-{
- crypto_pk_t *env;
- tor_assert(rsa);
- env = tor_malloc(sizeof(crypto_pk_t));
- env->refs = 1;
- env->key = rsa;
- return env;
-}
-
-/** Helper, used by tor-gencert.c. Return the RSA from a
- * crypto_pk_t. */
-RSA *
-crypto_pk_get_rsa_(crypto_pk_t *env)
-{
- return env->key;
-}
-
-/** used by tortls.c: get an equivalent EVP_PKEY* for a crypto_pk_t. Iff
- * private is set, include the private-key portion of the key. Return a valid
- * pointer on success, and NULL on failure. */
-MOCK_IMPL(EVP_PKEY *,
-crypto_pk_get_evp_pkey_,(crypto_pk_t *env, int private))
-{
- RSA *key = NULL;
- EVP_PKEY *pkey = NULL;
- tor_assert(env->key);
- if (private) {
- if (!(key = RSAPrivateKey_dup(env->key)))
- goto error;
- } else {
- if (!(key = RSAPublicKey_dup(env->key)))
- goto error;
- }
- if (!(pkey = EVP_PKEY_new()))
- goto error;
- if (!(EVP_PKEY_assign_RSA(pkey, key)))
- goto error;
- return pkey;
- error:
- if (pkey)
- EVP_PKEY_free(pkey);
- if (key)
- RSA_free(key);
- return NULL;
-}
-
/** Used by tortls.c: Get the DH* from a crypto_dh_t.
*/
DH *
@@ -438,38 +340,6 @@ crypto_dh_get_dh_(crypto_dh_t *dh)
return dh->dh;
}
-/** Allocate and return storage for a public key. The key itself will not yet
- * be set.
- */
-MOCK_IMPL(crypto_pk_t *,
-crypto_pk_new,(void))
-{
- RSA *rsa;
-
- rsa = RSA_new();
- tor_assert(rsa);
- return crypto_new_pk_from_rsa_(rsa);
-}
-
-/** Release a reference to an asymmetric key; when all the references
- * are released, free the key.
- */
-void
-crypto_pk_free_(crypto_pk_t *env)
-{
- if (!env)
- return;
-
- if (--env->refs > 0)
- return;
- tor_assert(env->refs == 0);
-
- if (env->key)
- RSA_free(env->key);
-
- tor_free(env);
-}
-
/** Allocate and return a new symmetric cipher using the provided key and iv.
* The key is <b>bits</b> bits long; the IV is CIPHER_IV_LEN bytes. Both
* must be provided. Key length must be 128, 192, or 256 */
@@ -528,543 +398,6 @@ crypto_cipher_free_(crypto_cipher_t *env)
/* public key crypto */
-/** Generate a <b>bits</b>-bit new public/private keypair in <b>env</b>.
- * Return 0 on success, -1 on failure.
- */
-MOCK_IMPL(int,
-crypto_pk_generate_key_with_bits,(crypto_pk_t *env, int bits))
-{
- tor_assert(env);
-
- if (env->key) {
- RSA_free(env->key);
- env->key = NULL;
- }
-
- {
- BIGNUM *e = BN_new();
- RSA *r = NULL;
- if (!e)
- goto done;
- if (! BN_set_word(e, 65537))
- goto done;
- r = RSA_new();
- if (!r)
- goto done;
- if (RSA_generate_key_ex(r, bits, e, NULL) == -1)
- goto done;
-
- env->key = r;
- r = NULL;
- done:
- if (e)
- BN_clear_free(e);
- if (r)
- RSA_free(r);
- }
-
- if (!env->key) {
- crypto_log_errors(LOG_WARN, "generating RSA key");
- return -1;
- }
-
- return 0;
-}
-
-/** A PEM callback that always reports a failure to get a password */
-static int
-pem_no_password_cb(char *buf, int size, int rwflag, void *u)
-{
- (void)buf;
- (void)size;
- (void)rwflag;
- (void)u;
- return 0;
-}
-
-/** Read a PEM-encoded private key from the <b>len</b>-byte string <b>s</b>
- * into <b>env</b>. Return 0 on success, -1 on failure. If len is -1,
- * the string is nul-terminated.
- */
-int
-crypto_pk_read_private_key_from_string(crypto_pk_t *env,
- const char *s, ssize_t len)
-{
- BIO *b;
-
- tor_assert(env);
- tor_assert(s);
- tor_assert(len < INT_MAX && len < SSIZE_T_CEILING);
-
- /* Create a read-only memory BIO, backed by the string 's' */
- b = BIO_new_mem_buf((char*)s, (int)len);
- if (!b)
- return -1;
-
- if (env->key)
- RSA_free(env->key);
-
- env->key = PEM_read_bio_RSAPrivateKey(b,NULL,pem_no_password_cb,NULL);
-
- BIO_free(b);
-
- if (!env->key) {
- crypto_log_errors(LOG_WARN, "Error parsing private key");
- return -1;
- }
- return 0;
-}
-
-/** Read a PEM-encoded private key from the file named by
- * <b>keyfile</b> into <b>env</b>. Return 0 on success, -1 on failure.
- */
-int
-crypto_pk_read_private_key_from_filename(crypto_pk_t *env,
- const char *keyfile)
-{
- char *contents;
- int r;
-
- /* Read the file into a string. */
- contents = read_file_to_str(keyfile, 0, NULL);
- if (!contents) {
- log_warn(LD_CRYPTO, "Error reading private key from \"%s\"", keyfile);
- return -1;
- }
-
- /* Try to parse it. */
- r = crypto_pk_read_private_key_from_string(env, contents, -1);
- memwipe(contents, 0, strlen(contents));
- tor_free(contents);
- if (r)
- return -1; /* read_private_key_from_string already warned, so we don't.*/
-
- /* Make sure it's valid. */
- if (crypto_pk_check_key(env) <= 0)
- return -1;
-
- return 0;
-}
-
-/** Helper function to implement crypto_pk_write_*_key_to_string. Return 0 on
- * success, -1 on failure. */
-static int
-crypto_pk_write_key_to_string_impl(crypto_pk_t *env, char **dest,
- size_t *len, int is_public)
-{
- BUF_MEM *buf;
- BIO *b;
- int r;
-
- tor_assert(env);
- tor_assert(env->key);
- tor_assert(dest);
-
- b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
- if (!b)
- return -1;
-
- /* Now you can treat b as if it were a file. Just use the
- * PEM_*_bio_* functions instead of the non-bio variants.
- */
- if (is_public)
- r = PEM_write_bio_RSAPublicKey(b, env->key);
- else
- r = PEM_write_bio_RSAPrivateKey(b, env->key, NULL,NULL,0,NULL,NULL);
-
- if (!r) {
- crypto_log_errors(LOG_WARN, "writing RSA key to string");
- BIO_free(b);
- return -1;
- }
-
- BIO_get_mem_ptr(b, &buf);
-
- *dest = tor_malloc(buf->length+1);
- memcpy(*dest, buf->data, buf->length);
- (*dest)[buf->length] = 0; /* nul terminate it */
- *len = buf->length;
-
- BIO_free(b);
-
- return 0;
-}
-
-/** PEM-encode the public key portion of <b>env</b> and write it to a
- * newly allocated string. On success, set *<b>dest</b> to the new
- * string, *<b>len</b> to the string's length, and return 0. On
- * failure, return -1.
- */
-int
-crypto_pk_write_public_key_to_string(crypto_pk_t *env, char **dest,
- size_t *len)
-{
- return crypto_pk_write_key_to_string_impl(env, dest, len, 1);
-}
-
-/** PEM-encode the private key portion of <b>env</b> and write it to a
- * newly allocated string. On success, set *<b>dest</b> to the new
- * string, *<b>len</b> to the string's length, and return 0. On
- * failure, return -1.
- */
-int
-crypto_pk_write_private_key_to_string(crypto_pk_t *env, char **dest,
- size_t *len)
-{
- return crypto_pk_write_key_to_string_impl(env, dest, len, 0);
-}
-
-/** Read a PEM-encoded public key from the first <b>len</b> characters of
- * <b>src</b>, and store the result in <b>env</b>. Return 0 on success, -1 on
- * failure.
- */
-int
-crypto_pk_read_public_key_from_string(crypto_pk_t *env, const char *src,
- size_t len)
-{
- BIO *b;
-
- tor_assert(env);
- tor_assert(src);
- tor_assert(len<INT_MAX);
-
- b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
- if (!b)
- return -1;
-
- BIO_write(b, src, (int)len);
-
- if (env->key)
- RSA_free(env->key);
- env->key = PEM_read_bio_RSAPublicKey(b, NULL, pem_no_password_cb, NULL);
- BIO_free(b);
- if (!env->key) {
- crypto_log_errors(LOG_WARN, "reading public key from string");
- return -1;
- }
-
- return 0;
-}
-
-/** Write the private key from <b>env</b> into the file named by <b>fname</b>,
- * PEM-encoded. Return 0 on success, -1 on failure.
- */
-int
-crypto_pk_write_private_key_to_filename(crypto_pk_t *env,
- const char *fname)
-{
- BIO *bio;
- char *cp;
- long len;
- char *s;
- int r;
-
- tor_assert(crypto_pk_private_ok(env));
-
- if (!(bio = BIO_new(BIO_s_mem())))
- return -1;
- if (PEM_write_bio_RSAPrivateKey(bio, env->key, NULL,NULL,0,NULL,NULL)
- == 0) {
- crypto_log_errors(LOG_WARN, "writing private key");
- BIO_free(bio);
- return -1;
- }
- len = BIO_get_mem_data(bio, &cp);
- tor_assert(len >= 0);
- s = tor_malloc(len+1);
- memcpy(s, cp, len);
- s[len]='\0';
- r = write_str_to_file(fname, s, 0);
- BIO_free(bio);
- memwipe(s, 0, strlen(s));
- tor_free(s);
- return r;
-}
-
-/** Return true iff <b>env</b> has a valid key.
- */
-int
-crypto_pk_check_key(crypto_pk_t *env)
-{
- int r;
- tor_assert(env);
-
- r = RSA_check_key(env->key);
- if (r <= 0)
- crypto_log_errors(LOG_WARN,"checking RSA key");
- return r;
-}
-
-/** Return true iff <b>key</b> contains the private-key portion of the RSA
- * key. */
-int
-crypto_pk_key_is_private(const crypto_pk_t *key)
-{
- tor_assert(key);
- return crypto_pk_private_ok(key);
-}
-
-/** Return true iff <b>env</b> contains a public key whose public exponent
- * equals 65537.
- */
-int
-crypto_pk_public_exponent_ok(crypto_pk_t *env)
-{
- tor_assert(env);
- tor_assert(env->key);
-
- const BIGNUM *e;
-
-#ifdef OPENSSL_1_1_API
- const BIGNUM *n, *d;
- RSA_get0_key(env->key, &n, &e, &d);
-#else
- e = env->key->e;
-#endif /* defined(OPENSSL_1_1_API) */
- return BN_is_word(e, 65537);
-}
-
-/** Compare the public-key components of a and b. Return less than 0
- * if a\<b, 0 if a==b, and greater than 0 if a\>b. A NULL key is
- * considered to be less than all non-NULL keys, and equal to itself.
- *
- * Note that this may leak information about the keys through timing.
- */
-int
-crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b)
-{
- int result;
- char a_is_non_null = (a != NULL) && (a->key != NULL);
- char b_is_non_null = (b != NULL) && (b->key != NULL);
- char an_argument_is_null = !a_is_non_null | !b_is_non_null;
-
- result = tor_memcmp(&a_is_non_null, &b_is_non_null, sizeof(a_is_non_null));
- if (an_argument_is_null)
- return result;
-
- const BIGNUM *a_n, *a_e;
- const BIGNUM *b_n, *b_e;
-
-#ifdef OPENSSL_1_1_API
- const BIGNUM *a_d, *b_d;
- RSA_get0_key(a->key, &a_n, &a_e, &a_d);
- RSA_get0_key(b->key, &b_n, &b_e, &b_d);
-#else
- a_n = a->key->n;
- a_e = a->key->e;
- b_n = b->key->n;
- b_e = b->key->e;
-#endif /* defined(OPENSSL_1_1_API) */
-
- tor_assert(a_n != NULL && a_e != NULL);
- tor_assert(b_n != NULL && b_e != NULL);
-
- result = BN_cmp(a_n, b_n);
- if (result)
- return result;
- return BN_cmp(a_e, b_e);
-}
-
-/** Compare the public-key components of a and b. Return non-zero iff
- * a==b. A NULL key is considered to be distinct from all non-NULL
- * keys, and equal to itself.
- *
- * Note that this may leak information about the keys through timing.
- */
-int
-crypto_pk_eq_keys(const crypto_pk_t *a, const crypto_pk_t *b)
-{
- return (crypto_pk_cmp_keys(a, b) == 0);
-}
-
-/** Return the size of the public key modulus in <b>env</b>, in bytes. */
-size_t
-crypto_pk_keysize(const crypto_pk_t *env)
-{
- tor_assert(env);
- tor_assert(env->key);
-
- return (size_t) RSA_size((RSA*)env->key);
-}
-
-/** Return the size of the public key modulus of <b>env</b>, in bits. */
-int
-crypto_pk_num_bits(crypto_pk_t *env)
-{
- tor_assert(env);
- tor_assert(env->key);
-
-#ifdef OPENSSL_1_1_API
- /* It's so stupid that there's no other way to check that n is valid
- * before calling RSA_bits().
- */
- const BIGNUM *n, *e, *d;
- RSA_get0_key(env->key, &n, &e, &d);
- tor_assert(n != NULL);
-
- return RSA_bits(env->key);
-#else /* !(defined(OPENSSL_1_1_API)) */
- tor_assert(env->key->n);
- return BN_num_bits(env->key->n);
-#endif /* defined(OPENSSL_1_1_API) */
-}
-
-/** Increase the reference count of <b>env</b>, and return it.
- */
-crypto_pk_t *
-crypto_pk_dup_key(crypto_pk_t *env)
-{
- tor_assert(env);
- tor_assert(env->key);
-
- env->refs++;
- return env;
-}
-
-#ifdef TOR_UNIT_TESTS
-/** For testing: replace dest with src. (Dest must have a refcount
- * of 1) */
-void
-crypto_pk_assign_(crypto_pk_t *dest, const crypto_pk_t *src)
-{
- tor_assert(dest);
- tor_assert(dest->refs == 1);
- tor_assert(src);
- RSA_free(dest->key);
- dest->key = RSAPrivateKey_dup(src->key);
-}
-#endif /* defined(TOR_UNIT_TESTS) */
-
-/** Make a real honest-to-goodness copy of <b>env</b>, and return it.
- * Returns NULL on failure. */
-crypto_pk_t *
-crypto_pk_copy_full(crypto_pk_t *env)
-{
- RSA *new_key;
- int privatekey = 0;
- tor_assert(env);
- tor_assert(env->key);
-
- if (crypto_pk_private_ok(env)) {
- new_key = RSAPrivateKey_dup(env->key);
- privatekey = 1;
- } else {
- new_key = RSAPublicKey_dup(env->key);
- }
- if (!new_key) {
- /* LCOV_EXCL_START
- *
- * We can't cause RSA*Key_dup() to fail, so we can't really test this.
- */
- log_err(LD_CRYPTO, "Unable to duplicate a %s key: openssl failed.",
- privatekey?"private":"public");
- crypto_log_errors(LOG_ERR,
- privatekey ? "Duplicating a private key" :
- "Duplicating a public key");
- tor_fragile_assert();
- return NULL;
- /* LCOV_EXCL_STOP */
- }
-
- return crypto_new_pk_from_rsa_(new_key);
-}
-
-/** Encrypt <b>fromlen</b> bytes from <b>from</b> with the public key
- * in <b>env</b>, using the padding method <b>padding</b>. On success,
- * write the result to <b>to</b>, and return the number of bytes
- * written. On failure, return -1.
- *
- * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
- * at least the length of the modulus of <b>env</b>.
- */
-int
-crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen,
- const char *from, size_t fromlen, int padding)
-{
- int r;
- tor_assert(env);
- tor_assert(from);
- tor_assert(to);
- tor_assert(fromlen<INT_MAX);
- tor_assert(tolen >= crypto_pk_keysize(env));
-
- r = RSA_public_encrypt((int)fromlen,
- (unsigned char*)from, (unsigned char*)to,
- env->key, crypto_get_rsa_padding(padding));
- if (r<0) {
- crypto_log_errors(LOG_WARN, "performing RSA encryption");
- return -1;
- }
- return r;
-}
-
-/** Decrypt <b>fromlen</b> bytes from <b>from</b> with the private key
- * in <b>env</b>, using the padding method <b>padding</b>. On success,
- * write the result to <b>to</b>, and return the number of bytes
- * written. On failure, return -1.
- *
- * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
- * at least the length of the modulus of <b>env</b>.
- */
-int
-crypto_pk_private_decrypt(crypto_pk_t *env, char *to,
- size_t tolen,
- const char *from, size_t fromlen,
- int padding, int warnOnFailure)
-{
- int r;
- tor_assert(env);
- tor_assert(from);
- tor_assert(to);
- tor_assert(env->key);
- tor_assert(fromlen<INT_MAX);
- tor_assert(tolen >= crypto_pk_keysize(env));
- if (!crypto_pk_key_is_private(env))
- /* Not a private key */
- return -1;
-
- r = RSA_private_decrypt((int)fromlen,
- (unsigned char*)from, (unsigned char*)to,
- env->key, crypto_get_rsa_padding(padding));
-
- if (r<0) {
- crypto_log_errors(warnOnFailure?LOG_WARN:LOG_DEBUG,
- "performing RSA decryption");
- return -1;
- }
- return r;
-}
-
-/** Check the signature in <b>from</b> (<b>fromlen</b> bytes long) with the
- * public key in <b>env</b>, using PKCS1 padding. On success, write the
- * signed data to <b>to</b>, and return the number of bytes written.
- * On failure, return -1.
- *
- * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
- * at least the length of the modulus of <b>env</b>.
- */
-MOCK_IMPL(int,
-crypto_pk_public_checksig,(const crypto_pk_t *env, char *to,
- size_t tolen,
- const char *from, size_t fromlen))
-{
- int r;
- tor_assert(env);
- tor_assert(from);
- tor_assert(to);
- tor_assert(fromlen < INT_MAX);
- tor_assert(tolen >= crypto_pk_keysize(env));
- r = RSA_public_decrypt((int)fromlen,
- (unsigned char*)from, (unsigned char*)to,
- env->key, RSA_PKCS1_PADDING);
-
- if (r<0) {
- crypto_log_errors(LOG_INFO, "checking RSA signature");
- return -1;
- }
- return r;
-}
-
/** Check a siglen-byte long signature at <b>sig</b> against
* <b>datalen</b> bytes of data at <b>data</b>, using the public key
* in <b>env</b>. Return 0 if <b>sig</b> is a correct signature for
@@ -1108,38 +441,6 @@ crypto_pk_public_checksig_digest,(crypto_pk_t *env, const char *data,
return 0;
}
-/** Sign <b>fromlen</b> bytes of data from <b>from</b> with the private key in
- * <b>env</b>, using PKCS1 padding. On success, write the signature to
- * <b>to</b>, and return the number of bytes written. On failure, return
- * -1.
- *
- * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
- * at least the length of the modulus of <b>env</b>.
- */
-int
-crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen,
- const char *from, size_t fromlen)
-{
- int r;
- tor_assert(env);
- tor_assert(from);
- tor_assert(to);
- tor_assert(fromlen < INT_MAX);
- tor_assert(tolen >= crypto_pk_keysize(env));
- if (!crypto_pk_key_is_private(env))
- /* Not a private key */
- return -1;
-
- r = RSA_private_encrypt((int)fromlen,
- (unsigned char*)from, (unsigned char*)to,
- (RSA*)env->key, RSA_PKCS1_PADDING);
- if (r<0) {
- crypto_log_errors(LOG_WARN, "generating RSA signature");
- return -1;
- }
- return r;
-}
-
/** Compute a SHA1 digest of <b>fromlen</b> bytes of data stored at
* <b>from</b>; sign the data with the private key in <b>env</b>, and
* store it in <b>to</b>. Return the number of bytes written on
@@ -1303,51 +604,6 @@ crypto_pk_obsolete_private_hybrid_decrypt(crypto_pk_t *env,
return -1;
}
-/** ASN.1-encode the public portion of <b>pk</b> into <b>dest</b>.
- * Return -1 on error, or the number of characters used on success.
- */
-int
-crypto_pk_asn1_encode(crypto_pk_t *pk, char *dest, size_t dest_len)
-{
- int len;
- unsigned char *buf = NULL;
-
- len = i2d_RSAPublicKey(pk->key, &buf);
- if (len < 0 || buf == NULL)
- return -1;
-
- if ((size_t)len > dest_len || dest_len > SIZE_T_CEILING) {
- OPENSSL_free(buf);
- return -1;
- }
- /* We don't encode directly into 'dest', because that would be illegal
- * type-punning. (C99 is smarter than me, C99 is smarter than me...)
- */
- memcpy(dest,buf,len);
- OPENSSL_free(buf);
- return len;
-}
-
-/** Decode an ASN.1-encoded public key from <b>str</b>; return the result on
- * success and NULL on failure.
- */
-crypto_pk_t *
-crypto_pk_asn1_decode(const char *str, size_t len)
-{
- RSA *rsa;
- unsigned char *buf;
- const unsigned char *cp;
- cp = buf = tor_malloc(len);
- memcpy(buf,str,len);
- rsa = d2i_RSAPublicKey(NULL, &cp, len);
- tor_free(buf);
- if (!rsa) {
- crypto_log_errors(LOG_WARN,"decoding public key");
- return NULL;
- }
- return crypto_new_pk_from_rsa_(rsa);
-}
-
/** Given a private or public key <b>pk</b>, put a SHA1 hash of the
* public key into <b>digest_out</b> (must have DIGEST_LEN bytes of space).
* Return 0 on success, -1 on failure.
@@ -1408,127 +664,6 @@ crypto_add_spaces_to_fp(char *out, size_t outlen, const char *in)
*out = '\0';
}
-/** Given a private or public key <b>pk</b>, put a fingerprint of the
- * public key into <b>fp_out</b> (must have at least FINGERPRINT_LEN+1 bytes of
- * space). Return 0 on success, -1 on failure.
- *
- * Fingerprints are computed as the SHA1 digest of the ASN.1 encoding
- * of the public key, converted to hexadecimal, in upper case, with a
- * space after every four digits.
- *
- * If <b>add_space</b> is false, omit the spaces.
- */
-int
-crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out, int add_space)
-{
- char digest[DIGEST_LEN];
- char hexdigest[HEX_DIGEST_LEN+1];
- if (crypto_pk_get_digest(pk, digest)) {
- return -1;
- }
- base16_encode(hexdigest,sizeof(hexdigest),digest,DIGEST_LEN);
- if (add_space) {
- crypto_add_spaces_to_fp(fp_out, FINGERPRINT_LEN+1, hexdigest);
- } else {
- strncpy(fp_out, hexdigest, HEX_DIGEST_LEN+1);
- }
- return 0;
-}
-
-/** Given a private or public key <b>pk</b>, put a hashed fingerprint of
- * the public key into <b>fp_out</b> (must have at least FINGERPRINT_LEN+1
- * bytes of space). Return 0 on success, -1 on failure.
- *
- * Hashed fingerprints are computed as the SHA1 digest of the SHA1 digest
- * of the ASN.1 encoding of the public key, converted to hexadecimal, in
- * upper case.
- */
-int
-crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out)
-{
- char digest[DIGEST_LEN], hashed_digest[DIGEST_LEN];
- if (crypto_pk_get_digest(pk, digest)) {
- return -1;
- }
- if (crypto_digest(hashed_digest, digest, DIGEST_LEN) < 0) {
- return -1;
- }
- base16_encode(fp_out, FINGERPRINT_LEN + 1, hashed_digest, DIGEST_LEN);
- return 0;
-}
-
-/** Given a crypto_pk_t <b>pk</b>, allocate a new buffer containing the
- * Base64 encoding of the DER representation of the private key as a NUL
- * terminated string, and return it via <b>priv_out</b>. Return 0 on
- * sucess, -1 on failure.
- *
- * It is the caller's responsibility to sanitize and free the resulting buffer.
- */
-int
-crypto_pk_base64_encode(const crypto_pk_t *pk, char **priv_out)
-{
- unsigned char *der = NULL;
- int der_len;
- int ret = -1;
-
- *priv_out = NULL;
-
- der_len = i2d_RSAPrivateKey(pk->key, &der);
- if (der_len < 0 || der == NULL)
- return ret;
-
- size_t priv_len = base64_encode_size(der_len, 0) + 1;
- char *priv = tor_malloc_zero(priv_len);
- if (base64_encode(priv, priv_len, (char *)der, der_len, 0) >= 0) {
- *priv_out = priv;
- ret = 0;
- } else {
- tor_free(priv);
- }
-
- memwipe(der, 0, der_len);
- OPENSSL_free(der);
- return ret;
-}
-
-/** Given a string containing the Base64 encoded DER representation of the
- * private key <b>str</b>, decode and return the result on success, or NULL
- * on failure.
- */
-crypto_pk_t *
-crypto_pk_base64_decode(const char *str, size_t len)
-{
- crypto_pk_t *pk = NULL;
-
- char *der = tor_malloc_zero(len + 1);
- int der_len = base64_decode(der, len, str, len);
- if (der_len <= 0) {
- log_warn(LD_CRYPTO, "Stored RSA private key seems corrupted (base64).");
- goto out;
- }
-
- const unsigned char *dp = (unsigned char*)der; /* Shut the compiler up. */
- RSA *rsa = d2i_RSAPrivateKey(NULL, &dp, der_len);
- if (!rsa) {
- crypto_log_errors(LOG_WARN, "decoding private key");
- goto out;
- }
-
- pk = crypto_new_pk_from_rsa_(rsa);
-
- /* Make sure it's valid. */
- if (crypto_pk_check_key(pk) <= 0) {
- crypto_pk_free(pk);
- pk = NULL;
- goto out;
- }
-
- out:
- memwipe(der, 0, len + 1);
- tor_free(der);
- return pk;
-}
-
/* symmetric crypto */
/** Encrypt <b>fromlen</b> bytes from <b>from</b> using the cipher
diff --git a/src/common/crypto.h b/src/common/crypto.h
index 3caa23773..a9c8837b9 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -20,6 +20,7 @@
#include "testsupport.h"
#include "compat.h"
#include "util.h"
+#include "crypto_rsa.h"
#include "keccak-tiny/keccak-tiny.h"
@@ -36,8 +37,6 @@
#define CIPHER_IV_LEN 16
/** Length of our symmetric cipher's keys of 256-bit. */
#define CIPHER256_KEY_LEN 32
-/** Length of our public keys. */
-#define PK_BYTES (1024/8)
/** Length of our DH keys. */
#define DH_BYTES (1024/8)
@@ -54,12 +53,6 @@
* signs removed. */
#define BASE64_DIGEST512_LEN 86
-/** Constant used to indicate OAEP padding for public-key encryption */
-#define PK_PKCS1_OAEP_PADDING 60002
-
-/** Number of bytes added for PKCS1-OAEP padding. */
-#define PKCS1_OAEP_PADDING_OVERHEAD 42
-
/** Length of encoded public key fingerprints, including space; but not
* including terminating NUL. */
#define FINGERPRINT_LEN 49
@@ -92,7 +85,6 @@ typedef struct {
char d[N_COMMON_DIGEST_ALGORITHMS][DIGEST256_LEN];
} common_digests_t;
-typedef struct crypto_pk_t crypto_pk_t;
typedef struct aes_cnt_cipher crypto_cipher_t;
typedef struct crypto_digest_t crypto_digest_t;
typedef struct crypto_xof_t crypto_xof_t;
@@ -111,10 +103,6 @@ void crypto_thread_cleanup(void);
int crypto_global_cleanup(void);
/* environment setup */
-MOCK_DECL(crypto_pk_t *,crypto_pk_new,(void));
-void crypto_pk_free_(crypto_pk_t *env);
-#define crypto_pk_free(pk) FREE_AND_NULL(crypto_pk_t, crypto_pk_free_, (pk))
-
void crypto_set_tls_dh_prime(void);
crypto_cipher_t *crypto_cipher_new(const char *key);
crypto_cipher_t *crypto_cipher_new_with_bits(const char *key, int bits);
@@ -126,47 +114,10 @@ void crypto_cipher_free_(crypto_cipher_t *env);
#define crypto_cipher_free(c) \
FREE_AND_NULL(crypto_cipher_t, crypto_cipher_free_, (c))
-/* public key crypto */
-MOCK_DECL(int, crypto_pk_generate_key_with_bits,(crypto_pk_t *env, int bits));
-#define crypto_pk_generate_key(env) \
- crypto_pk_generate_key_with_bits((env), (PK_BYTES*8))
-
-int crypto_pk_read_private_key_from_filename(crypto_pk_t *env,
- const char *keyfile);
-int crypto_pk_write_public_key_to_string(crypto_pk_t *env,
- char **dest, size_t *len);
-int crypto_pk_write_private_key_to_string(crypto_pk_t *env,
- char **dest, size_t *len);
-int crypto_pk_read_public_key_from_string(crypto_pk_t *env,
- const char *src, size_t len);
-int crypto_pk_read_private_key_from_string(crypto_pk_t *env,
- const char *s, ssize_t len);
-int crypto_pk_write_private_key_to_filename(crypto_pk_t *env,
- const char *fname);
-
-int crypto_pk_check_key(crypto_pk_t *env);
-int crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b);
-int crypto_pk_eq_keys(const crypto_pk_t *a, const crypto_pk_t *b);
-size_t crypto_pk_keysize(const crypto_pk_t *env);
-int crypto_pk_num_bits(crypto_pk_t *env);
-crypto_pk_t *crypto_pk_dup_key(crypto_pk_t *orig);
-crypto_pk_t *crypto_pk_copy_full(crypto_pk_t *orig);
-int crypto_pk_key_is_private(const crypto_pk_t *key);
-int crypto_pk_public_exponent_ok(crypto_pk_t *env);
-
-int crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen,
- const char *from, size_t fromlen, int padding);
-int crypto_pk_private_decrypt(crypto_pk_t *env, char *to, size_t tolen,
- const char *from, size_t fromlen,
- int padding, int warnOnFailure);
-MOCK_DECL(int, crypto_pk_public_checksig,(const crypto_pk_t *env,
- char *to, size_t tolen,
- const char *from, size_t fromlen));
+/* public key crypto */
MOCK_DECL(int, crypto_pk_public_checksig_digest,(crypto_pk_t *env,
const char *data, size_t datalen,
const char *sig, size_t siglen));
-int crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen,
- const char *from, size_t fromlen);
int crypto_pk_private_sign_digest(crypto_pk_t *env, char *to, size_t tolen,
const char *from, size_t fromlen);
int crypto_pk_obsolete_public_hybrid_encrypt(crypto_pk_t *env, char *to,
@@ -177,17 +128,9 @@ int crypto_pk_obsolete_private_hybrid_decrypt(crypto_pk_t *env, char *to,
size_t tolen,
const char *from, size_t fromlen,
int padding, int warnOnFailure);
-
-int crypto_pk_asn1_encode(crypto_pk_t *pk, char *dest, size_t dest_len);
-crypto_pk_t *crypto_pk_asn1_decode(const char *str, size_t len);
int crypto_pk_get_digest(const crypto_pk_t *pk, char *digest_out);
int crypto_pk_get_common_digests(crypto_pk_t *pk,
common_digests_t *digests_out);
-int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out,int add_space);
-int crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out);
-
-int crypto_pk_base64_encode(const crypto_pk_t *pk, char **priv_out);
-crypto_pk_t *crypto_pk_base64_decode(const char *str, size_t len);
/* symmetric crypto */
const char *crypto_cipher_get_key(crypto_cipher_t *env);
@@ -303,13 +246,7 @@ void memwipe(void *mem, uint8_t byte, size_t sz);
/* Prototypes for private functions only used by tortls.c, crypto.c, and the
* unit tests. */
-struct rsa_st;
-struct evp_pkey_st;
struct dh_st;
-struct rsa_st *crypto_pk_get_rsa_(crypto_pk_t *env);
-crypto_pk_t *crypto_new_pk_from_rsa_(struct rsa_st *rsa);
-MOCK_DECL(struct evp_pkey_st *, crypto_pk_get_evp_pkey_,(crypto_pk_t *env,
- int private));
struct dh_st *crypto_dh_get_dh_(crypto_dh_t *dh);
void crypto_add_spaces_to_fp(char *out, size_t outlen, const char *in);
@@ -326,7 +263,6 @@ extern int break_strongest_rng_fallback;
#endif /* defined(CRYPTO_PRIVATE) */
#ifdef TOR_UNIT_TESTS
-void crypto_pk_assign_(crypto_pk_t *dest, const crypto_pk_t *src);
digest_algorithm_t crypto_digest_get_algorithm(crypto_digest_t *digest);
#endif
diff --git a/src/common/crypto_rsa.c b/src/common/crypto_rsa.c
new file mode 100644
index 000000000..1308c4819
--- /dev/null
+++ b/src/common/crypto_rsa.c
@@ -0,0 +1,878 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file crypto_rsa.c
+ * \brief Block of functions related with RSA utilities and operations.
+ **/
+
+#include "crypto_rsa.h"
+
+/** A public key, or a public/private key-pair. */
+struct crypto_pk_t
+{
+ int refs; /**< reference count, so we don't have to copy keys */
+ RSA *key; /**< The key itself */
+};
+
+/** Return the number of bytes added by padding method <b>padding</b>.
+ */
+static inline int
+crypto_get_rsa_padding_overhead(int padding)
+{
+ switch (padding)
+ {
+ case RSA_PKCS1_OAEP_PADDING: return PKCS1_OAEP_PADDING_OVERHEAD;
+ default: tor_assert(0); return -1; // LCOV_EXCL_LINE
+ }
+}
+
+/** Given a padding method <b>padding</b>, return the correct OpenSSL constant.
+ */
+static inline int
+crypto_get_rsa_padding(int padding)
+{
+ switch (padding)
+ {
+ case PK_PKCS1_OAEP_PADDING: return RSA_PKCS1_OAEP_PADDING;
+ default: tor_assert(0); return -1; // LCOV_EXCL_LINE
+ }
+}
+
+/** used internally: quicly validate a crypto_pk_t object as a private key.
+ * Return 1 iff the public key is valid, 0 if obviously invalid.
+ */
+static int
+crypto_pk_private_ok(const crypto_pk_t *k)
+{
+#ifdef OPENSSL_1_1_API
+ if (!k || !k->key)
+ return 0;
+
+ const BIGNUM *p, *q;
+ RSA_get0_factors(k->key, &p, &q);
+ return p != NULL; /* XXX/yawning: Should we check q? */
+#else /* !(defined(OPENSSL_1_1_API)) */
+ return k && k->key && k->key->p;
+#endif /* defined(OPENSSL_1_1_API) */
+}
+
+/** used by tortls.c: wrap an RSA* in a crypto_pk_t. */
+crypto_pk_t *
+crypto_new_pk_from_rsa_(RSA *rsa)
+{
+ crypto_pk_t *env;
+ tor_assert(rsa);
+ env = tor_malloc(sizeof(crypto_pk_t));
+ env->refs = 1;
+ env->key = rsa;
+ return env;
+}
+
+/** Helper, used by tor-gencert.c. Return the RSA from a
+ * crypto_pk_t. */
+RSA *
+crypto_pk_get_rsa_(crypto_pk_t *env)
+{
+ return env->key;
+}
+
+/** used by tortls.c: get an equivalent EVP_PKEY* for a crypto_pk_t. Iff
+ * private is set, include the private-key portion of the key. Return a valid
+ * pointer on success, and NULL on failure. */
+MOCK_IMPL(EVP_PKEY *,
+crypto_pk_get_evp_pkey_,(crypto_pk_t *env, int private))
+{
+ RSA *key = NULL;
+ EVP_PKEY *pkey = NULL;
+ tor_assert(env->key);
+ if (private) {
+ if (!(key = RSAPrivateKey_dup(env->key)))
+ goto error;
+ } else {
+ if (!(key = RSAPublicKey_dup(env->key)))
+ goto error;
+ }
+ if (!(pkey = EVP_PKEY_new()))
+ goto error;
+ if (!(EVP_PKEY_assign_RSA(pkey, key)))
+ goto error;
+ return pkey;
+ error:
+ if (pkey)
+ EVP_PKEY_free(pkey);
+ if (key)
+ RSA_free(key);
+ return NULL;
+}
+
+/** Allocate and return storage for a public key. The key itself will not yet
+ * be set.
+ */
+MOCK_IMPL(crypto_pk_t *,
+crypto_pk_new,(void))
+{
+ RSA *rsa;
+
+ rsa = RSA_new();
+ tor_assert(rsa);
+ return crypto_new_pk_from_rsa_(rsa);
+}
+
+/** Release a reference to an asymmetric key; when all the references
+ * are released, free the key.
+ */
+void
+crypto_pk_free_(crypto_pk_t *env)
+{
+ if (!env)
+ return;
+
+ if (--env->refs > 0)
+ return;
+ tor_assert(env->refs == 0);
+
+ if (env->key)
+ RSA_free(env->key);
+
+ tor_free(env);
+}
+
+/** Generate a <b>bits</b>-bit new public/private keypair in <b>env</b>.
+ * Return 0 on success, -1 on failure.
+ */
+MOCK_IMPL(int,
+crypto_pk_generate_key_with_bits,(crypto_pk_t *env, int bits))
+{
+ tor_assert(env);
+
+ if (env->key) {
+ RSA_free(env->key);
+ env->key = NULL;
+ }
+
+ {
+ BIGNUM *e = BN_new();
+ RSA *r = NULL;
+ if (!e)
+ goto done;
+ if (! BN_set_word(e, 65537))
+ goto done;
+ r = RSA_new();
+ if (!r)
+ goto done;
+ if (RSA_generate_key_ex(r, bits, e, NULL) == -1)
+ goto done;
+
+ env->key = r;
+ r = NULL;
+ done:
+ if (e)
+ BN_clear_free(e);
+ if (r)
+ RSA_free(r);
+ }
+
+ if (!env->key) {
+ crypto_log_errors(LOG_WARN, "generating RSA key");
+ return -1;
+ }
+
+ return 0;
+}
+
+/** A PEM callback that always reports a failure to get a password */
+static int
+pem_no_password_cb(char *buf, int size, int rwflag, void *u)
+{
+ (void)buf;
+ (void)size;
+ (void)rwflag;
+ (void)u;
+ return 0;
+}
+
+/** Read a PEM-encoded private key from the <b>len</b>-byte string <b>s</b>
+ * into <b>env</b>. Return 0 on success, -1 on failure. If len is -1,
+ * the string is nul-terminated.
+ */
+int
+crypto_pk_read_private_key_from_string(crypto_pk_t *env,
+ const char *s, ssize_t len)
+{
+ BIO *b;
+
+ tor_assert(env);
+ tor_assert(s);
+ tor_assert(len < INT_MAX && len < SSIZE_T_CEILING);
+
+ /* Create a read-only memory BIO, backed by the string 's' */
+ b = BIO_new_mem_buf((char*)s, (int)len);
+ if (!b)
+ return -1;
+
+ if (env->key)
+ RSA_free(env->key);
+
+ env->key = PEM_read_bio_RSAPrivateKey(b,NULL,pem_no_password_cb,NULL);
+
+ BIO_free(b);
+
+ if (!env->key) {
+ crypto_log_errors(LOG_WARN, "Error parsing private key");
+ return -1;
+ }
+ return 0;
+}
+
+/** Read a PEM-encoded private key from the file named by
+ * <b>keyfile</b> into <b>env</b>. Return 0 on success, -1 on failure.
+ */
+int
+crypto_pk_read_private_key_from_filename(crypto_pk_t *env,
+ const char *keyfile)
+{
+ char *contents;
+ int r;
+
+ /* Read the file into a string. */
+ contents = read_file_to_str(keyfile, 0, NULL);
+ if (!contents) {
+ log_warn(LD_CRYPTO, "Error reading private key from \"%s\"", keyfile);
+ return -1;
+ }
+
+ /* Try to parse it. */
+ r = crypto_pk_read_private_key_from_string(env, contents, -1);
+ memwipe(contents, 0, strlen(contents));
+ tor_free(contents);
+ if (r)
+ return -1; /* read_private_key_from_string already warned, so we don't.*/
+
+ /* Make sure it's valid. */
+ if (crypto_pk_check_key(env) <= 0)
+ return -1;
+
+ return 0;
+}
+
+/** Helper function to implement crypto_pk_write_*_key_to_string. Return 0 on
+ * success, -1 on failure. */
+static int
+crypto_pk_write_key_to_string_impl(crypto_pk_t *env, char **dest,
+ size_t *len, int is_public)
+{
+ BUF_MEM *buf;
+ BIO *b;
+ int r;
+
+ tor_assert(env);
+ tor_assert(env->key);
+ tor_assert(dest);
+
+ b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
+ if (!b)
+ return -1;
+
+ /* Now you can treat b as if it were a file. Just use the
+ * PEM_*_bio_* functions instead of the non-bio variants.
+ */
+ if (is_public)
+ r = PEM_write_bio_RSAPublicKey(b, env->key);
+ else
+ r = PEM_write_bio_RSAPrivateKey(b, env->key, NULL,NULL,0,NULL,NULL);
+
+ if (!r) {
+ crypto_log_errors(LOG_WARN, "writing RSA key to string");
+ BIO_free(b);
+ return -1;
+ }
+
+ BIO_get_mem_ptr(b, &buf);
+
+ *dest = tor_malloc(buf->length+1);
+ memcpy(*dest, buf->data, buf->length);
+ (*dest)[buf->length] = 0; /* nul terminate it */
+ *len = buf->length;
+
+ BIO_free(b);
+
+ return 0;
+}
+
+/** PEM-encode the public key portion of <b>env</b> and write it to a
+ * newly allocated string. On success, set *<b>dest</b> to the new
+ * string, *<b>len</b> to the string's length, and return 0. On
+ * failure, return -1.
+ */
+int
+crypto_pk_write_public_key_to_string(crypto_pk_t *env, char **dest,
+ size_t *len)
+{
+ return crypto_pk_write_key_to_string_impl(env, dest, len, 1);
+}
+
+/** PEM-encode the private key portion of <b>env</b> and write it to a
+ * newly allocated string. On success, set *<b>dest</b> to the new
+ * string, *<b>len</b> to the string's length, and return 0. On
+ * failure, return -1.
+ */
+int
+crypto_pk_write_private_key_to_string(crypto_pk_t *env, char **dest,
+ size_t *len)
+{
+ return crypto_pk_write_key_to_string_impl(env, dest, len, 0);
+}
+
+/** Read a PEM-encoded public key from the first <b>len</b> characters of
+ * <b>src</b>, and store the result in <b>env</b>. Return 0 on success, -1 on
+ * failure.
+ */
+int
+crypto_pk_read_public_key_from_string(crypto_pk_t *env, const char *src,
+ size_t len)
+{
+ BIO *b;
+
+ tor_assert(env);
+ tor_assert(src);
+ tor_assert(len<INT_MAX);
+
+ b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
+ if (!b)
+ return -1;
+
+ BIO_write(b, src, (int)len);
+
+ if (env->key)
+ RSA_free(env->key);
+ env->key = PEM_read_bio_RSAPublicKey(b, NULL, pem_no_password_cb, NULL);
+ BIO_free(b);
+ if (!env->key) {
+ crypto_log_errors(LOG_WARN, "reading public key from string");
+ return -1;
+ }
+
+ return 0;
+}
+
+/** Write the private key from <b>env</b> into the file named by <b>fname</b>,
+ * PEM-encoded. Return 0 on success, -1 on failure.
+ */
+int
+crypto_pk_write_private_key_to_filename(crypto_pk_t *env,
+ const char *fname)
+{
+ BIO *bio;
+ char *cp;
+ long len;
+ char *s;
+ int r;
+
+ tor_assert(crypto_pk_private_ok(env));
+
+ if (!(bio = BIO_new(BIO_s_mem())))
+ return -1;
+ if (PEM_write_bio_RSAPrivateKey(bio, env->key, NULL,NULL,0,NULL,NULL)
+ == 0) {
+ crypto_log_errors(LOG_WARN, "writing private key");
+ BIO_free(bio);
+ return -1;
+ }
+ len = BIO_get_mem_data(bio, &cp);
+ tor_assert(len >= 0);
+ s = tor_malloc(len+1);
+ memcpy(s, cp, len);
+ s[len]='\0';
+ r = write_str_to_file(fname, s, 0);
+ BIO_free(bio);
+ memwipe(s, 0, strlen(s));
+ tor_free(s);
+ return r;
+}
+
+/** Return true iff <b>env</b> has a valid key.
+ */
+int
+crypto_pk_check_key(crypto_pk_t *env)
+{
+ int r;
+ tor_assert(env);
+
+ r = RSA_check_key(env->key);
+ if (r <= 0)
+ crypto_log_errors(LOG_WARN,"checking RSA key");
+ return r;
+}
+
+/** Return true iff <b>key</b> contains the private-key portion of the RSA
+ * key. */
+int
+crypto_pk_key_is_private(const crypto_pk_t *key)
+{
+ tor_assert(key);
+ return crypto_pk_private_ok(key);
+}
+
+/** Return true iff <b>env</b> contains a public key whose public exponent
+ * equals 65537.
+ */
+int
+crypto_pk_public_exponent_ok(crypto_pk_t *env)
+{
+ tor_assert(env);
+ tor_assert(env->key);
+
+ const BIGNUM *e;
+
+#ifdef OPENSSL_1_1_API
+ const BIGNUM *n, *d;
+ RSA_get0_key(env->key, &n, &e, &d);
+#else
+ e = env->key->e;
+#endif /* defined(OPENSSL_1_1_API) */
+ return BN_is_word(e, 65537);
+}
+
+/** Compare the public-key components of a and b. Return less than 0
+ * if a\<b, 0 if a==b, and greater than 0 if a\>b. A NULL key is
+ * considered to be less than all non-NULL keys, and equal to itself.
+ *
+ * Note that this may leak information about the keys through timing.
+ */
+int
+crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b)
+{
+ int result;
+ char a_is_non_null = (a != NULL) && (a->key != NULL);
+ char b_is_non_null = (b != NULL) && (b->key != NULL);
+ char an_argument_is_null = !a_is_non_null | !b_is_non_null;
+
+ result = tor_memcmp(&a_is_non_null, &b_is_non_null, sizeof(a_is_non_null));
+ if (an_argument_is_null)
+ return result;
+
+ const BIGNUM *a_n, *a_e;
+ const BIGNUM *b_n, *b_e;
+
+#ifdef OPENSSL_1_1_API
+ const BIGNUM *a_d, *b_d;
+ RSA_get0_key(a->key, &a_n, &a_e, &a_d);
+ RSA_get0_key(b->key, &b_n, &b_e, &b_d);
+#else
+ a_n = a->key->n;
+ a_e = a->key->e;
+ b_n = b->key->n;
+ b_e = b->key->e;
+#endif /* defined(OPENSSL_1_1_API) */
+
+ tor_assert(a_n != NULL && a_e != NULL);
+ tor_assert(b_n != NULL && b_e != NULL);
+
+ result = BN_cmp(a_n, b_n);
+ if (result)
+ return result;
+ return BN_cmp(a_e, b_e);
+}
+
+/** Compare the public-key components of a and b. Return non-zero iff
+ * a==b. A NULL key is considered to be distinct from all non-NULL
+ * keys, and equal to itself.
+ *
+ * Note that this may leak information about the keys through timing.
+ */
+int
+crypto_pk_eq_keys(const crypto_pk_t *a, const crypto_pk_t *b)
+{
+ return (crypto_pk_cmp_keys(a, b) == 0);
+}
+
+/** Return the size of the public key modulus in <b>env</b>, in bytes. */
+size_t
+crypto_pk_keysize(const crypto_pk_t *env)
+{
+ tor_assert(env);
+ tor_assert(env->key);
+
+ return (size_t) RSA_size((RSA*)env->key);
+}
+
+/** Return the size of the public key modulus of <b>env</b>, in bits. */
+int
+crypto_pk_num_bits(crypto_pk_t *env)
+{
+ tor_assert(env);
+ tor_assert(env->key);
+
+#ifdef OPENSSL_1_1_API
+ /* It's so stupid that there's no other way to check that n is valid
+ * before calling RSA_bits().
+ */
+ const BIGNUM *n, *e, *d;
+ RSA_get0_key(env->key, &n, &e, &d);
+ tor_assert(n != NULL);
+
+ return RSA_bits(env->key);
+#else /* !(defined(OPENSSL_1_1_API)) */
+ tor_assert(env->key->n);
+ return BN_num_bits(env->key->n);
+#endif /* defined(OPENSSL_1_1_API) */
+}
+
+/** Increase the reference count of <b>env</b>, and return it.
+ */
+crypto_pk_t *
+crypto_pk_dup_key(crypto_pk_t *env)
+{
+ tor_assert(env);
+ tor_assert(env->key);
+
+ env->refs++;
+ return env;
+}
+
+#ifdef TOR_UNIT_TESTS
+/** For testing: replace dest with src. (Dest must have a refcount
+ * of 1) */
+void
+crypto_pk_assign_(crypto_pk_t *dest, const crypto_pk_t *src)
+{
+ tor_assert(dest);
+ tor_assert(dest->refs == 1);
+ tor_assert(src);
+ RSA_free(dest->key);
+ dest->key = RSAPrivateKey_dup(src->key);
+}
+#endif /* defined(TOR_UNIT_TESTS) */
+
+/** Make a real honest-to-goodness copy of <b>env</b>, and return it.
+ * Returns NULL on failure. */
+crypto_pk_t *
+crypto_pk_copy_full(crypto_pk_t *env)
+{
+ RSA *new_key;
+ int privatekey = 0;
+ tor_assert(env);
+ tor_assert(env->key);
+
+ if (crypto_pk_private_ok(env)) {
+ new_key = RSAPrivateKey_dup(env->key);
+ privatekey = 1;
+ } else {
+ new_key = RSAPublicKey_dup(env->key);
+ }
+ if (!new_key) {
+ /* LCOV_EXCL_START
+ *
+ * We can't cause RSA*Key_dup() to fail, so we can't really test this.
+ */
+ log_err(LD_CRYPTO, "Unable to duplicate a %s key: openssl failed.",
+ privatekey?"private":"public");
+ crypto_log_errors(LOG_ERR,
+ privatekey ? "Duplicating a private key" :
+ "Duplicating a public key");
+ tor_fragile_assert();
+ return NULL;
+ /* LCOV_EXCL_STOP */
+ }
+
+ return crypto_new_pk_from_rsa_(new_key);
+}
+
+/** Encrypt <b>fromlen</b> bytes from <b>from</b> with the public key
+ * in <b>env</b>, using the padding method <b>padding</b>. On success,
+ * write the result to <b>to</b>, and return the number of bytes
+ * written. On failure, return -1.
+ *
+ * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
+ * at least the length of the modulus of <b>env</b>.
+ */
+int
+crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen,
+ const char *from, size_t fromlen, int padding)
+{
+ int r;
+ tor_assert(env);
+ tor_assert(from);
+ tor_assert(to);
+ tor_assert(fromlen<INT_MAX);
+ tor_assert(tolen >= crypto_pk_keysize(env));
+
+ r = RSA_public_encrypt((int)fromlen,
+ (unsigned char*)from, (unsigned char*)to,
+ env->key, crypto_get_rsa_padding(padding));
+ if (r<0) {
+ crypto_log_errors(LOG_WARN, "performing RSA encryption");
+ return -1;
+ }
+ return r;
+}
+
+/** Decrypt <b>fromlen</b> bytes from <b>from</b> with the private key
+ * in <b>env</b>, using the padding method <b>padding</b>. On success,
+ * write the result to <b>to</b>, and return the number of bytes
+ * written. On failure, return -1.
+ *
+ * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
+ * at least the length of the modulus of <b>env</b>.
+ */
+int
+crypto_pk_private_decrypt(crypto_pk_t *env, char *to,
+ size_t tolen,
+ const char *from, size_t fromlen,
+ int padding, int warnOnFailure)
+{
+ int r;
+ tor_assert(env);
+ tor_assert(from);
+ tor_assert(to);
+ tor_assert(env->key);
+ tor_assert(fromlen<INT_MAX);
+ tor_assert(tolen >= crypto_pk_keysize(env));
+ if (!crypto_pk_key_is_private(env))
+ /* Not a private key */
+ return -1;
+
+ r = RSA_private_decrypt((int)fromlen,
+ (unsigned char*)from, (unsigned char*)to,
+ env->key, crypto_get_rsa_padding(padding));
+
+ if (r<0) {
+ crypto_log_errors(warnOnFailure?LOG_WARN:LOG_DEBUG,
+ "performing RSA decryption");
+ return -1;
+ }
+ return r;
+}
+
+/** Check the signature in <b>from</b> (<b>fromlen</b> bytes long) with the
+ * public key in <b>env</b>, using PKCS1 padding. On success, write the
+ * signed data to <b>to</b>, and return the number of bytes written.
+ * On failure, return -1.
+ *
+ * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
+ * at least the length of the modulus of <b>env</b>.
+ */
+MOCK_IMPL(int,
+crypto_pk_public_checksig,(const crypto_pk_t *env, char *to,
+ size_t tolen,
+ const char *from, size_t fromlen))
+{
+ int r;
+ tor_assert(env);
+ tor_assert(from);
+ tor_assert(to);
+ tor_assert(fromlen < INT_MAX);
+ tor_assert(tolen >= crypto_pk_keysize(env));
+ r = RSA_public_decrypt((int)fromlen,
+ (unsigned char*)from, (unsigned char*)to,
+ env->key, RSA_PKCS1_PADDING);
+
+ if (r<0) {
+ crypto_log_errors(LOG_INFO, "checking RSA signature");
+ return -1;
+ }
+ return r;
+}
+
+/** Sign <b>fromlen</b> bytes of data from <b>from</b> with the private key in
+ * <b>env</b>, using PKCS1 padding. On success, write the signature to
+ * <b>to</b>, and return the number of bytes written. On failure, return
+ * -1.
+ *
+ * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
+ * at least the length of the modulus of <b>env</b>.
+ */
+int
+crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen,
+ const char *from, size_t fromlen)
+{
+ int r;
+ tor_assert(env);
+ tor_assert(from);
+ tor_assert(to);
+ tor_assert(fromlen < INT_MAX);
+ tor_assert(tolen >= crypto_pk_keysize(env));
+ if (!crypto_pk_key_is_private(env))
+ /* Not a private key */
+ return -1;
+
+ r = RSA_private_encrypt((int)fromlen,
+ (unsigned char*)from, (unsigned char*)to,
+ (RSA*)env->key, RSA_PKCS1_PADDING);
+ if (r<0) {
+ crypto_log_errors(LOG_WARN, "generating RSA signature");
+ return -1;
+ }
+ return r;
+}
+
+/** ASN.1-encode the public portion of <b>pk</b> into <b>dest</b>.
+ * Return -1 on error, or the number of characters used on success.
+ */
+int
+crypto_pk_asn1_encode(crypto_pk_t *pk, char *dest, size_t dest_len)
+{
+ int len;
+ unsigned char *buf = NULL;
+
+ len = i2d_RSAPublicKey(pk->key, &buf);
+ if (len < 0 || buf == NULL)
+ return -1;
+
+ if ((size_t)len > dest_len || dest_len > SIZE_T_CEILING) {
+ OPENSSL_free(buf);
+ return -1;
+ }
+ /* We don't encode directly into 'dest', because that would be illegal
+ * type-punning. (C99 is smarter than me, C99 is smarter than me...)
+ */
+ memcpy(dest,buf,len);
+ OPENSSL_free(buf);
+ return len;
+}
+
+/** Decode an ASN.1-encoded public key from <b>str</b>; return the result on
+ * success and NULL on failure.
+ */
+crypto_pk_t *
+crypto_pk_asn1_decode(const char *str, size_t len)
+{
+ RSA *rsa;
+ unsigned char *buf;
+ const unsigned char *cp;
+ cp = buf = tor_malloc(len);
+ memcpy(buf,str,len);
+ rsa = d2i_RSAPublicKey(NULL, &cp, len);
+ tor_free(buf);
+ if (!rsa) {
+ crypto_log_errors(LOG_WARN,"decoding public key");
+ return NULL;
+ }
+ return crypto_new_pk_from_rsa_(rsa);
+}
+
+/** Given a private or public key <b>pk</b>, put a fingerprint of the
+ * public key into <b>fp_out</b> (must have at least FINGERPRINT_LEN+1 bytes of
+ * space). Return 0 on success, -1 on failure.
+ *
+ * Fingerprints are computed as the SHA1 digest of the ASN.1 encoding
+ * of the public key, converted to hexadecimal, in upper case, with a
+ * space after every four digits.
+ *
+ * If <b>add_space</b> is false, omit the spaces.
+ */
+int
+crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out, int add_space)
+{
+ char digest[DIGEST_LEN];
+ char hexdigest[HEX_DIGEST_LEN+1];
+ if (crypto_pk_get_digest(pk, digest)) {
+ return -1;
+ }
+ base16_encode(hexdigest,sizeof(hexdigest),digest,DIGEST_LEN);
+ if (add_space) {
+ crypto_add_spaces_to_fp(fp_out, FINGERPRINT_LEN+1, hexdigest);
+ } else {
+ strncpy(fp_out, hexdigest, HEX_DIGEST_LEN+1);
+ }
+ return 0;
+}
+
+/** Given a private or public key <b>pk</b>, put a hashed fingerprint of
+ * the public key into <b>fp_out</b> (must have at least FINGERPRINT_LEN+1
+ * bytes of space). Return 0 on success, -1 on failure.
+ *
+ * Hashed fingerprints are computed as the SHA1 digest of the SHA1 digest
+ * of the ASN.1 encoding of the public key, converted to hexadecimal, in
+ * upper case.
+ */
+int
+crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out)
+{
+ char digest[DIGEST_LEN], hashed_digest[DIGEST_LEN];
+ if (crypto_pk_get_digest(pk, digest)) {
+ return -1;
+ }
+ if (crypto_digest(hashed_digest, digest, DIGEST_LEN) < 0) {
+ return -1;
+ }
+ base16_encode(fp_out, FINGERPRINT_LEN + 1, hashed_digest, DIGEST_LEN);
+ return 0;
+}
+
+/** Given a crypto_pk_t <b>pk</b>, allocate a new buffer containing the
+ * Base64 encoding of the DER representation of the private key as a NUL
+ * terminated string, and return it via <b>priv_out</b>. Return 0 on
+ * sucess, -1 on failure.
+ *
+ * It is the caller's responsibility to sanitize and free the resulting buffer.
+ */
+int
+crypto_pk_base64_encode(const crypto_pk_t *pk, char **priv_out)
+{
+ unsigned char *der = NULL;
+ int der_len;
+ int ret = -1;
+
+ *priv_out = NULL;
+
+ der_len = i2d_RSAPrivateKey(pk->key, &der);
+ if (der_len < 0 || der == NULL)
+ return ret;
+
+ size_t priv_len = base64_encode_size(der_len, 0) + 1;
+ char *priv = tor_malloc_zero(priv_len);
+ if (base64_encode(priv, priv_len, (char *)der, der_len, 0) >= 0) {
+ *priv_out = priv;
+ ret = 0;
+ } else {
+ tor_free(priv);
+ }
+
+ memwipe(der, 0, der_len);
+ OPENSSL_free(der);
+ return ret;
+}
+
+/** Given a string containing the Base64 encoded DER representation of the
+ * private key <b>str</b>, decode and return the result on success, or NULL
+ * on failure.
+ */
+crypto_pk_t *
+crypto_pk_base64_decode(const char *str, size_t len)
+{
+ crypto_pk_t *pk = NULL;
+
+ char *der = tor_malloc_zero(len + 1);
+ int der_len = base64_decode(der, len, str, len);
+ if (der_len <= 0) {
+ log_warn(LD_CRYPTO, "Stored RSA private key seems corrupted (base64).");
+ goto out;
+ }
+
+ const unsigned char *dp = (unsigned char*)der; /* Shut the compiler up. */
+ RSA *rsa = d2i_RSAPrivateKey(NULL, &dp, der_len);
+ if (!rsa) {
+ crypto_log_errors(LOG_WARN, "decoding private key");
+ goto out;
+ }
+
+ pk = crypto_new_pk_from_rsa_(rsa);
+
+ /* Make sure it's valid. */
+ if (crypto_pk_check_key(pk) <= 0) {
+ crypto_pk_free(pk);
+ pk = NULL;
+ goto out;
+ }
+
+ out:
+ memwipe(der, 0, len + 1);
+ tor_free(der);
+ return pk;
+}
+
diff --git a/src/common/crypto_rsa.h b/src/common/crypto_rsa.h
new file mode 100644
index 000000000..e38451fed
--- /dev/null
+++ b/src/common/crypto_rsa.h
@@ -0,0 +1,100 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file crypto_rsa.h
+ *
+ * \brief Headers for crypto_rsa.c
+ **/
+
+#ifndef TOR_CRYPTO_RSA_H
+#define TOR_CRYPTO_RSA_H
+
+#include "orconfig.h"
+
+#include <stdio.h>
+#include "torint.h"
+#include "testsupport.h"
+#include "compat.h"
+#include "util.h"
+
+/** Length of our public keys. */
+#define PK_BYTES (1024/8)
+
+/** Constant used to indicate OAEP padding for public-key encryption */
+#define PK_PKCS1_OAEP_PADDING 60002
+
+/** Number of bytes added for PKCS1-OAEP padding. */
+#define PKCS1_OAEP_PADDING_OVERHEAD 42
+
+typedef struct crypto_pk_t crypto_pk_t;
+
+/* RSA enviroment setup */
+MOCK_DECL(crypto_pk_t *,crypto_pk_new,(void));
+void crypto_pk_free_(crypto_pk_t *env);
+#define crypto_pk_free(pk) FREE_AND_NULL(crypto_pk_t, crypto_pk_free_, (pk))
+
+/* public key crypto */
+MOCK_DECL(int, crypto_pk_generate_key_with_bits,(crypto_pk_t *env, int bits));
+#define crypto_pk_generate_key(env) \
+ crypto_pk_generate_key_with_bits((env), (PK_BYTES*8))
+
+int crypto_pk_read_private_key_from_filename(crypto_pk_t *env,
+ const char *keyfile);
+int crypto_pk_write_public_key_to_string(crypto_pk_t *env,
+ char **dest, size_t *len);
+int crypto_pk_write_private_key_to_string(crypto_pk_t *env,
+ char **dest, size_t *len);
+int crypto_pk_read_public_key_from_string(crypto_pk_t *env,
+ const char *src, size_t len);
+int crypto_pk_read_private_key_from_string(crypto_pk_t *env,
+ const char *s, ssize_t len);
+int crypto_pk_write_private_key_to_filename(crypto_pk_t *env,
+ const char *fname);
+
+int crypto_pk_check_key(crypto_pk_t *env);
+int crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b);
+int crypto_pk_eq_keys(const crypto_pk_t *a, const crypto_pk_t *b);
+size_t crypto_pk_keysize(const crypto_pk_t *env);
+int crypto_pk_num_bits(crypto_pk_t *env);
+crypto_pk_t *crypto_pk_dup_key(crypto_pk_t *orig);
+crypto_pk_t *crypto_pk_copy_full(crypto_pk_t *orig);
+int crypto_pk_key_is_private(const crypto_pk_t *key);
+int crypto_pk_public_exponent_ok(crypto_pk_t *env);
+
+int crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen,
+ const char *from, size_t fromlen, int padding);
+int crypto_pk_private_decrypt(crypto_pk_t *env, char *to, size_t tolen,
+ const char *from, size_t fromlen,
+ int padding, int warnOnFailure);
+MOCK_DECL(int, crypto_pk_public_checksig,(const crypto_pk_t *env,
+ char *to, size_t tolen,
+ const char *from, size_t fromlen));
+int crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen,
+ const char *from, size_t fromlen);
+int crypto_pk_asn1_encode(crypto_pk_t *pk, char *dest, size_t dest_len);
+crypto_pk_t *crypto_pk_asn1_decode(const char *str, size_t len);
+int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out,int add_space);
+int crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out);
+
+int crypto_pk_base64_encode(const crypto_pk_t *pk, char **priv_out);
+crypto_pk_t *crypto_pk_base64_decode(const char *str, size_t len);
+
+/* Prototypes for private functions only used by tortls.c, crypto.c, and the
+ * unit tests. */
+struct rsa_st;
+struct rsa_st *crypto_pk_get_rsa_(crypto_pk_t *env);
+crypto_pk_t *crypto_new_pk_from_rsa_(struct rsa_st *rsa);
+MOCK_DECL(struct evp_pkey_st *, crypto_pk_get_evp_pkey_,(crypto_pk_t *env,
+ int private));
+struct evp_pkey_st;
+
+#ifdef TOR_UNIT_TESTS
+void crypto_pk_assign_(crypto_pk_t *dest, const crypto_pk_t *src);
+#endif
+
+#endif
+
1
0
commit 51377a917e246b28f437f54f8adc9a472b91b5f4
Merge: 44a9ed7df bdaf7ebc2
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu Feb 1 12:10:07 2018 -0500
Merge branch 'bug24658-rsa_squashed'
src/common/crypto.c | 918 ++---------------------------------------------
src/common/crypto.h | 68 +---
src/common/crypto_rsa.c | 923 ++++++++++++++++++++++++++++++++++++++++++++++++
src/common/crypto_rsa.h | 104 ++++++
src/common/include.am | 2 +
5 files changed, 1064 insertions(+), 951 deletions(-)
1
0