Fragen? Antworten! Siehe auch: Alternativlos
Konzeptionell bin ich ja ein Freund von Rust. Was die sich da an Neuerungen überlegt haben, das hat die Industrie insgesamt vor sich hergetrieben.
Von welchem Nachteil rede ich denn dann? Nun, ich baue hier regelmäßig mein Firefox selbst.
Mozilla stellt der Reihe nach Teile von Firefox auf Rust um.
Das ist ja auch gut so.
Aber zwei Effekte zeigen sich dabei schnell. Der erste ist, dass Rust nicht parallel baut. Neben den ganzen C++-Teilen, die vom Build-Prozess schön auf die Cores verteilt werden, läuft da dann halt ein cargo build für sowas wie 15 Minuten auf einem Core und baut den Rust-Kram. Noch gibt es genug C++-Zeug, dass das noch wenig zu Lasten der CPU-Auslastung geht, aber wenn man inkrementell baut und sich in der Zeit drei C++ und zwei Rust Quellcodedateien geändert haben, dann merkt man das deutlich, denn bei Rust ist die Unterscheidung zwischen Compiler und Linker anders verschoben. Der scheint immer eine Art LTO-Pass zu machen. Jedenfalls kommt es vor, dass der C++-Teil fertig ist und dann das make mit einer 100%-Auslastung auf einem Kern ewig lang an Rust herumrödelt.
Das ist das erste Problem. Das zweite Problem ist noch schwerwiegender. Rust verbraucht echt viel RAM. Ich habe hier eine Kiste mit 16 GB RAM. Die reicht bei praktisch allen Projekten, um die aus der Ramdisk (tmpfs) zu bauen. Nicht so bei Firefox. Da musste ich schon vor einer Weile die Quellen auf der Platte haben, weil sonst der Build mit out of memory abbrach. Jetzt ist es so, dass der Build auch beim von-Platte-bauen gerne mit out of memory abbricht. Stellt sich raus: Der LTO-Teil in dem Rust-Teil von Firefox schluckt mal eben sowas wie 13 GB am Stück. Wenn du da noch ein paar C++-Dateien parallel zu bauen versuchst, dann ist Ende Gelände.
Ich beobachte das mit großer Sorge, wie sorglos Entwickler mit dem Speicherbedarf ihrer Software umgehen. Ich habe noch zwei andere Projekte, bei denen der Speicher knapp wird. Qt muss ich auch von Platte bauen, nicht von Ramdisk. Und LLVM hat neuerdings einen Fortran-Compiler drin. Ich weiß nicht, was die da gemacht haben, aber das Bauen davon muss ich auf zwei Kerne zur Zeit beschränken, sonst frisst das zu viel RAM. Ich vermute eine Template-Instanziierungs-Hölle oder sowas. Der Fortran-Compiler setzt bei LLVM auf ein neueres Fundament als der C++-Compiler, ein generalisiertes Compilerframework namens mlir (ist auch Teil von LLVM).
Chrome und Libreoffice benutze ich nicht und habe ich daher auch nicht zu bauen versucht. Ich vermute mal, das wird mit 16 GB auch knapp.
Update: Dass Rust nicht parallel baut ist eigentlich auch nicht korrekt. Ich kann daher gerade das bei Firefox beobachtete Verhalten nicht erklären. Das liegt allerdings auch schon ein bisschen zurück, denn Firefox hat vor einer Weile angefangen, einfach gefühlt immer darauf zu bestehen, dass man einen komplett neuen Build startet und nicht inkrementell baut. Jedenfalls definitiv immer zwischen Versionen. Insofern kommt der Fall bei mir kaum noch vor, dass ich auf einen Rust warten muss bei Firefox.
Wer da Präsentationen hochladen darf, hat Admin-Zugriff.
Update: Hanno Böck hat den Bigbluebutton-Leuten das im Mai (!) gemeldet. Seit dem sitzen die darauf. Stellt sich raus: Man kann da ne Präsentation hochladen und der Server öffnet das dann in Libreoffice. Lasst mich da völlig klar ansagen: DAS IST EINE FURCHTBAR SCHLECHTE IDEE. Dass das Projekt diese Idee überhaupt implementiert hat, ist für mich ein Zeichen, dass ich nie wieder mit Software interagieren will, bei der diese Leute Teil der Entscheidungsfindung waren. Die sind fürs Leben verbrannt. Das ist ungefähr so schlau wie im Winter einen Krieg gegen Russland zu starten. Nicht nur offensichtlich eine schlechte Idee sondern da sind sogar schon vorher andere mit auf die Fresse geflogen. Diese Officeformate sind eine einzige Schlangengrube und die Wahrscheinlichkeit, dass das irgendjemand anständig implementiert kriegt, ist sehr nahe an Null. Aber in diesem Fall musste gar kein Exploit her, denn die Dateiformate haben (völlig ohne Not, möchte ich anmerken!) ein Feature, über das man externe Ressourcen über eine URL einbinden kann. Da kann man natürlich auch eine file://-Url nehmen und sich beliebige Dateien auf dem Server anzeigen lassen.
Vom Niveau her ist das absolut am unteren Ende der Skala. Tiefer sinkt nur Cisco mit ihren ständigen Hintertüren und "vergessenen, versehentlich hart einkodierten Passwörtern".
Abonnenten meldeten, dass AVG und Avast die taz vom 14.8. als gefährlich einstufen, siehe Virustotal.Die Witze schreiben sich praktisch von selbst!Auf Nachfrage hat Avast bestätigt, dass das kein false positive ist ("Our virus specialists have been working on this problem and they informed me that this detection is correct.").
Nun habe ich die Datei mal einer bisection unterzogen und es liegt an der Seite 15.
Dort ist ein Link auf http://antifa.de/ im Text.
Und wenn ich jetzt mit Libreoffice ein Dokument mache, wo nur ein paar Worte mit dem Link zu http://antifa.de/ drin sind, dann schlagen AVG und Avast auch darauf an.
Mir fehlen die Worte.
Kauft mehr Schlangenöl! Wegen der Sicherheit!!
Update: Wartet, geht noch weiter!
Achso, und dass von der entsprechenden Komponente des Virenscanners deswegen der ganze Server dl.taz.de als Malwareserver ("infiziert mit URL:blacklist") eingestuft und Verbindungen dahin unterbrochen werden, versteht sich von selbst.
Golem hat mal beim BSI einen Informationsfreiheitsantrag gestellt und die haben ihm die Studie geschickt — aber sie dürfen sie nur lesen, nicht veröffentlichen.
Sehr ärgerlich ist aus meiner Sicht auch dieses Detail hier:
Das BSI bestätigte uns, dass es die Ergebnisse nicht an die Entwickler der anderen Bibliotheken weitergegeben hatDie anderen sind LibreSSL und NSS. Und um das hier ging es:
So gibt es etwa Hinweise auf Compilerwarnungen und eine Einschätzung, wie schwerwiegend diese sind, außerdem eine Auflistung von Fehlern in den State Machines der TLS-Handshake-Implementierung und Hinweise, an welchen Stellen der Code besser gegen Timing-Angriffe geschützt werden sollte.Ja, äh, was sprach denn da bitte dagegen, das den Projekten mitzuteilen?! Bei Botan haben sie ja nicht nur Bescheid gesagt sondern sogar Patches hingeschickt!
Das hinterlässt ja einen noch schlechteren Nachgeschmack als vorher, und das war vorher schon nicht gut. Wow, BSI, das war ja mal ein echter Rückschritt. Habt ihr schon aufgegeben? Glaubt ihr, euch glaubt eh nie wieder jemand was? Gut, könnte was dran sein, zumal mit dem Cyberclown jetzt. Tja.
LibreSSL 2.5.1 to 2.5.3 lacks TLS certificate verification if
SSL_get_verify_result is relied upon for a later check of a
verification result, in a use case where a user-provided verification
callback returns 1, as demonstrated by acceptance of invalid
certificates by nginx.
OMFG
Das einstige Prestigeprojekt LiMux war schon 2014 beim neuen Oberbürgermeister Dieter Reiter (SPD) in Ungnade gefallen, der sich unwidersprochen als Fan der Redmonder bezeichnen ließ und zu seiner Zeit als Wirtschaftsreferent dafür sorgte, dass Microsoft Deutschland seine Konzernzentrale von Unterschleißheim nach München verlegte.Oh ach so, die Verräterpartei! Na das ist ja mal wieder eine Überraschung!1!!
Wer jetzt dachte, das habe was mit Kosten zu tun, der möge sich mal dieses Randdetail durchlesen:
Zugleich räumte sie aber ein, dass in der IT-Abteilung in München viele Stellen unbesetzt seien, die Rede ist von 70 von 300. Die Lücken sollen dem Vernehmen nach durch Freiberufler zu Tagessätzen von 1500 Euro geschlossen werden.Was für eine Frechheit!
Mir hatte da übrigens vor einer Weile ein Insider eine lange Mail geschrieben, die ich mir für diesen Zeitpunkt aufgehoben hatte, aber ich finde sie gerade nicht mehr. Mist. Nun, da stand im Wesentlichen drin, was man sich so denken würde über deutsche Behörden. Beschissene Arbeitsatmosphäre, Inkompetenz und Ass Covering auf allen Ebenen, niemand geht irgendwelche Risiken ein, alle Reparatur- und verbesserungsmaßnahmen werden daher von unteren Mitarbeitern auf eigenes Risiko durchgeführt — und wir reden hier von sowas wie "Linux nicht nur einmalig von CD installieren sondern auch Patches einspielen". Das war eine Dystopie sondergleichen, die diese Mail schilderte. So ein Mist. Naja, denkt euch die Details selbst dazu. Kein Wunder, dass die 70 freie Stellen haben. Wer will in so einer Umgebung arbeiten?
Der Punkt der Mail war jedenfalls, dass an genau keinem Punkt Linux irgendeine Schuld hatte. Es gab da so Rahmenbedingungen wie "der Personalrat setzt pro Desktop-Änderung eine Neuschulung aller Angestellten durch", und so weiter. Und daraus folgte dann "keine Updates einspielen, nicht dass das optisch was ändert und wir alle Leute neu schulen müssen".
Die Mail erhob noch weitergehende Vorwürfe über Nepotismus und "die Ausschreibung wird von dem einen Zulieferer formuliert, damit er auch wieder den Zuschlag kriegt", aber betrachtet das mal noch mehr als Gerücht als den Rest der Vorwürfe. Der Einsender machte deutlich den Punkt, dass da keine technischen Probleme mit Linux oder Libreoffice das Problem waren. Wer schonmal mit Libreoffice gearbeitet hat, der wird verstehen, dass das eine starke Aussage ist :-)
Ich weiß nicht, ob der Einsender tatsächlich Insider war, insofern: mit einer Prise Salz nehmen. Aber es klang für mich schon authentisch nach Behördenkoller.
Update: Bei Netzpolitik.org liest sich die selbe Nummer gleich viel weniger endgültig.
Update: Ein Einsender erzählt:
Du musst mal mit jemandem reden, der mit dem Münchner System mit Externen kommunizieren muss oder, noch schlimmer, außerhalb von Büro und Bürostunden das System nutzen will. Hilfsweise tun es auch Anwender anstelle von IT-Experten oder Leuten, die sich dafür halten. Da geht in der Regel noch nicht mal die Mail, weil die das über die Jahre nicht gebacken gekriegt haben bzw. wollten, oder weil die Linux-Jungs und Mädels schlicht und ergreifend nicht begriffen haben, warum das jemand haben wollen könnte.
Das Linux-Projekt ist nicht an Linux gescheitert, sondern an der Ignoranz und der Hybris der IT-Verantwortlichen. Wenn man den Leuten noch nicht einmal in Ansätzen die Funktionalität gibt, die sie draußen oder zuhause haben, dann schieben sie das halt aufs System, und nicht auf die Verantwortlichen.
Ich habe seit einigen Jahren Kontakt zu Leuten in der Stadtverwaltung, die regelmäßig reisen: Wenn die kein privates Equipment mitnehmen, sind sie völlig incommunicado. Tödlich, wenn der Rest der Welt always on ist.
Das erste, was bei Rust auffällt: Man kann es nicht aus den Sourcen bauen. Ich möchte immer gerne vermeiden, anderer Leute Binaries auszuführen. Das ist eine Policy bei mir. Wenn ich es nicht selbst gebaut habe, will ich es nicht haben. Es gibt nur wenige Ausnahmen, bei denen der Buildprozess zu furchtbar ist, oder so fragil, dass das selbstgebaute Binary am Ende nicht so gut funktioniert wie das "offizielle", weil die auf irgendwelche speziellen Compilerversionen setzen oder so. Die einzigen Sachen, die ich hier nicht selber baue, sind im Moment Chrome, Libreoffice (falls ich das so einmal pro Jahr mal brauche) und ripgrep. Und ripgrep wollte ich mal ändern. Außerdem finde ich Rust von den Konzepten her spannend und will mal damit rumspielen.
Erste Erkenntnis: Die neueren Versionen von openssl-rust können OpenSSL 1.1. Allerdings kann man Rust nicht aus den Sourcen bauen, ohne schon eine Version von Rust zu haben. Das finde ich sehr schade. Das ist ein Spannungsfeld, das viele Programmiersprachen betrifft. Programmiersprachen haben Angst, erst ernst genommen zu werden, wenn sie self-hosting sind. Die Download-Seite von Rust will einem erstmal Binärpakete aufdrücken, was ich immer ein schlechtes Zeichen finde. Binärpakete ist der schlechte Kompromiss für Leute, die zu doof sind, aus den Sourcen zu bauen. Und die sind bei Rust nicht Zielgruppe. Dafür ist die Lernkurve zu steil bei Rust.
Aber wenn man runterscrollt, kriegt man auch die Quellen. Und wenn man da configure und make aufruft, dann … zieht der ungefragt ein Binärpaket einer älteren Rust-Version, installiert das, und baut dann damit. Das vereint die Nachteile von "aus Binärpaket installieren" mit der Wartezeit von "aus Quellen bauen" und weicht etwaigen Vorteilen weiträumig aus. Völlig gaga. Aber es gibt eine configure-Option, dass man das installierte Rust haben will.
Aus meiner Sicht ist der perfekte Kompromiss, was Ocaml macht. Da kommen die Quellen mit einem kleinen C-Bootstrap-Interpreter, und der baut dann den Compiler, und der baut sich dann nochmal selber. So muss das sein. Ist es aber bei Rust leider nicht. Bei Go auch nicht mehr, übrigens.
Anyway. Wenn man das über sich ergehen lässt und Rust aus den Sourcen baut, dann kriegt man eine Version ohne cargo. cargo ist das Packaging-Tool von Rust. Ohne cargo kann man nichts bauen. Insbesondere kann man nicht cargo ohne cargo bauen. Und da muss ich sagen: WTF? Selbst GNU make kann man ohne make bauen! Das ist ja wohl absolut offensichtlich, dass man solche Henne-Ei-Probleme vermeiden will!?
Insgesamt muss ich also meine Kritik zurückziehen, dass Rust immer noch nicht mit OpenSSL 1.1 klarkommt. Tut es, nur halt anscheinend nicht in der stable-Version. Aber diese cargo-Situation finde ich ja noch schlimmer als die OpenSSL-Situation war. Meine Güte, liebe Rust-Leute! Bin ich ernsthaft der erste, der über das Bootstrapping nachdenkt?!
Oh ach ja, ripgrep. ripgrep kann man nicht mit der Stable-Version von Rust kompilieren. Und auch nicht mit der Beta-Version. Das braucht die Bleeding-Edge-Version.
Nun ist Rust eine relativ frische Sprache und sie haben daher eine Familienpackung Verständnis für so Kinderkrankheiten verdient. Aber dann nennt euren Scheiß halt nicht Version 1.irgendwas sondern 0.irgendwas.
Update: Wie sich rausstellt, lässt sich ripgrep doch mit älteren Rust-Versionen kompilieren, allerdings dann ohne SIMD-Support. Wenn ich ripgrep ohne SIMD-Support haben wollen würde, könnte ich auch grep -r benutzen oder silver surfer. Was ich versucht habe, um ripgrep zu bauen: git clone + cd ripgrep + ./compile. Mir erklärt jetzt jemand per Mail, dass das gar nicht der offizielle Build-Weg ist unter Rust. Das hat sich mir als Rust-Neuling so nicht erschlossen. Und es wirft die Frage auf, wieso der Autor von ripgrep dann ein configure-Skript beliegen muss und das dann auch noch was anderes tut als der Standard-Buildweg. Ist der Standard-Weg kaputt und man kann die zusätzlichen Flags, die er da benötigt, nicht einstellen?
Update: Ein paar Leute fragen jetzt rhetorisch, wie ich denn meinen C-Compiler gebootstrappt habe. Das Argument könnte man gelten lassen, wenn es von Rust aus möglich wäre, einen C-Compiler zu bootstrappen. Ist es aber nicht. Aber mit einem C-Compiler kann man diverse andere Sprachen bootstrappen, u.a. Go, Lisp, Forth, Scheme, Ocaml, C++, Javascript, Java, .... Aber um kurz die rhetorische Frage zu beantworten: Meinen C-Compiler habe ich cross-compiled. :-)
Update: Bei Ocaml ist es auch nicht so rosig, wie ich es geschildert habe. Der in C geschriebene Interpreter ist bloß ein Bytecode-Interpreter, und ein vor-gebauter Bytecode liegt dann halt binär bei. Ist auch nicht ideal. Das ist halt auch ein schwieriges Problem. Ich frage mich halt, ob man bei sowas wie Rust nicht trennen kann. Mein Verständnis war, dass die Sprache Rust schon ziemlich final ist und die Dynamik eher in der Laufzeitumgebung und den Libraries ist. Dann könnte man ja beispielsweise einen Minimal-Interpreter oder Nach-C-Übersetzer bauen, der sich die komplizierten Dinge wie Borrow-Checker, Solver und Optimizer spart.
Immerhin: Wenn ihr immer schön präemptiv geupdated habt, dann besteht jetzt kein akuter Handlungsbedarf.
Nun, dann lest euch doch mal durch, mit wem wir es bei Paul Magnette wirklich zu tun haben. Ich spoiler mal ein bisschen
A suave, Cambridge-educated former professor of EU constitutional law at the Université Libre de Bruxelles, […]Magnette was a European affairs scholar long before he was a politician. He specialized in EU constitutional issues for much of the 2000s, and European Commission President Jean-Claude Juncker tried to play on his commitment to the broader European project.
Mit anderen Worten: Das ist wahrscheinlich der Einzige weit und breit, der den CETA-Text mal durchgelesen und auch verstanden hat. (Danke, Kurt)
Die Shared Library hat eine neue Version, d.h. man muss einmal alle Software neu bauen. wget, curl, alles. curl baut gegen das neue OpenSSL, aber ist damit allein auf weiter Flur. wget musste ich patchen, mutt musste ich patchen, neon (für Subversion) musste ich patchen. git war gut. Der SSL-Code aus gatling geht überraschenderweise auch ohne Änderung. Aber sonst so? Kahlschlag.
Python baut zum Beispiel nur die Module _hashlib und _ssl nicht mit. Ihr könnt euch ja ausmalen, was das alleine an Folge-Infrastrukturapokalypse nach sich zieht. Bei mir konkret geht daher gerade SCons nicht, welches das Buildsystem von serf ist, ohne das ich Subversion nicht reparieren kann.
Die Perl-Module gingen auch. Aber so gefühlt ist über die Hälfte der Software jetzt zerbrochen.
Ich hätte mir ehrlich gesagt erhofft, dass die OpenSSL-Leute da eine klitzekleine Warnung in ihren Bart säuseln, bevor sie so eine Apokalypse lostreten.
Auf der anderen Seite ist das ja auch ein schöner Impuls, mal generell von diesem OpenSSL wegzumigrieren.
Update: Bei Debian hat es auch das eine oder andere Paket zerrissen.
Update: Ein Leserbrief dazu:
Wollte nur kurz darauf hinweisen, daß die API-Änderungen bei OpenSSL 1.1 nicht nur jede Menge inkompatibilitäten nach sich ziehen, bei denen was laut kaputt geht (compiletime error), sondern auch API-Änderungen dabei sind, die stillschweigend security-buigs erzeugen können.
Beispiel: Die HMAC manpage sagt:
HMAC_Init_ex() initializes or reuses a HMAC_CTX structure to use the
function evp_md and key key. Either can be NULL, in which case the
existing one will be reused.HMAC_Init_ex liefert erst seit kurzem einen Fehlerstatus zurück - früher hatte sie keinen Rückgabewert und konnte nicht fehlschlagen. Daher testet auch ne Menge Software nicht auf sowas, und das wra bis vor kurzem auch korrekt.
In OpenSSL 1.1 gibt es aber folgende Änderung:
/* If we are changing MD then we must have a key */
if (md != NULL && md != ctx->md && (key == NULL || len < 0))
return 0;d.h. anders als dokumentiert, kann nicht "either NULL" sein. Aber alte Software kann das nicht prüfen, und welche HMAC dann im Endeffekt berechnet wird, steht in den Sternen.
Die Reaktion von OpenSSL upstream war, die Doku zu ändern.
D.h. nicht nur breaked openssl die API (teilweise unnötig) so, daß Programme nicht mehr kompilieren, nein Programme, die mal korrekt waren und jetzt immer noch kompilieren haben jetzt unter Umständen größere Sicherheitslöcher.
(Es gibt eine Reihe ähnlicher stiller API-Änderungen in OpenSSL 1.1)
(und ja, wegmigrieren hört sich gut an, aber es gibt häufig keine alternative mit gleichen Funktionsumfang ohne diese Probleme - gnutls hat z.b. mindestens bis vor kurzem kein RSA-OEAP padding unterstützt, sondern nur das extrem anfällige kaputte PKCS-padding).
Und zu meiner Aussage, dass interne Typen opak gemacht wurden, kommentiert der Einsender noch:
Das, so würde ich sagen, ist falsch. Erstens sind viele dieser Datentypen nicht intern, sondern man musste früher darauf zugreifen weil es keine accessors gab und das auch so dokumentiert war, und zweitens ist das Hautproblem nicht, daß die Typen opak sind, sondern daß man früher structs selbst allozieren musste und das jetzt nicht mehr geht, d.h. alter code nicht compiliert, auch wenn er nicht auf irgendwelche strukturen zugegriffen hat.
Der Hintergrund für viele solche Änderungen war, daß man man structs nicht mehr auf dem Stack hat - sehr löblich. Das wurde aber so gelöst, daß man jetzt alles dynamisch über eine spezielle openssl-Funktion allozieren muss, die es früher nicht gab, und code, der die structs selbst deklariert hast, schlägt fehl, weil der Typ opak ist, auch, wenn garnicht darauf zugegriffen wird.
Im Allgemeinen ist es deshalb nicht möglich, code zu schreiben, der mit der neuen und der alten API funktioniert (also, ohne #if-massengrab).
Mir ist aufgefallen, dass auch Code mit #if-Massengrab bricht mit Version 1.1. Früher konnte man mit OPENSSL_NO_SSL2 gucken, ob die verwendete Version mit SSL2-Support kommt oder nicht. OpenSSL 1.1 hat kein SSL2 mehr, aber deklariert auch dieses Präprozessorsymbol nicht.
Update: Noch ein Leserbrief zur OpenSSL-Version:
OpenSSL 1.1 Unterstützung für Python ist fertig, hängt aber noch im Codereview, weil Python Core Devs mit OpenSSL-Kenntnissen Mangelware sind. Neben mir gibt es zur Zeit nur drei weitere aktive, von denen zwei mit anderen Dingen beschäftigt sind. Zum Glück habe ich schon vor einem halben Jahr mit meinem Patch angefangen angefangen und einige Patches bei OpenSSL eingereicht. Andernfalls würden mir jetzt die Zugriffsfunktionen auf diverse struct member fehlen.
https://bugs.python.org/issue26470Zwei weitere Punkte:
1) Es reicht nicht, nur auf OPENSSL_VERSION_NUMBER zu prüfen. LibreSSL hat OPENSSL_VERSION_NUMBER gekapert und missbraucht das Makro für die eigene Versionsnummber 2.x. Man muss also immer noch zusätzlich auf nicht-LibreSSL testen:
#if (OPENSSL_VERSION_NUMBER > 0x10100000L) || !defined(LIBRESSL_VERSION_NUMBER)2) Nach sweet32 hat OpenSSL 1.0.2 nur noch einen sicheren Algorithmus für symmetrische Verschlüsselung. ChaCha20 gibt es erst in 1.1. Ich habe mit Richard Salz vom OpenSSL Team gesprochen. Er teilt meine Sorge, trotzdem wird OpenSSL 1.0.2 LTS keine Unterstützung für ChaCha20 erhalten.
https://twitter.com/ChristianHeimes/status/768434388052938756
Nur falls jemand dachte, hey, dann bleib ich halt bei OpenSSL 1.0.2! Übrigens sei an der Stelle der Hinweis erlaubt, dass Version vor 1.0.1 schon länger gar keine Updates mehr kriegen. Man sieht vereinzelt da draußen noch OpenSSL 0.9er-Versionen rumfliegen. Ganz, GANZ gruselig.
Das mit Chacha20 war bei mir übrigens auch der Auslöser für den Umstieg auf 1.1. OpenSSL 1.1 hat nämlich endlich Support für die Dan-Bernstein-Erfindungen Chacha20 und Poly1305. Je älter ich werde, desto weniger traue ich Krypto-Sachen, die nicht von djb kommen oder von ihm abgenickt wurden. Der Mann hat einfach zu oft Recht behalten, als alle anderen abgewunken, relativiert oder gelacht haben. Ich sehe übrigens keinen inhaltlichen Grund, wieso man Chacha20 und Poly1305 nicht auch in 1.0.2 haben sollte, das gibt es seit Jahren für 1.0x-Versionen von OpenSSL als Patch, und LibreSSL hat es auch von Anfang an drin. Finde ich absolut unverständlich, was das OpenSSL-Team sich da leistet.
Oh und unter uns: Wenn euer Code so kacke ist, dass schon Cisco in ihm Remote Code Execution findet, dann solltet ihr über einen Karrierewechsel nachdenken.
Na dann guckt mal hier. (Danke, Gerd)
Infrastruktur wird überhaupt nur beurteilt, wenn sie versagt - ansonsten wird sie gar nicht wahrgenommen. Der Linux-Kernel wird an "ReiserFS/btrfs/XFS/ext4 hat meine Daten gefressen" und an "Der Kernel cored, wenn die Kiste aus dem Sleep aufwacht" gemessen und nicht an "Oh, der write(2) System Call hat meine Daten tatsächlich auf die Platte geschrieben.Ich stimme dem im Detail nicht zu (ich bewerte den Kernel auch nach neuen Features und Performancegewinnen bei alten Features), aber das kann man auch durch geschickte Wortauslegung wegdefinieren. Die Ausführungen finde ich trotzdem weiterhelfend und konnte das so auch schon beobachten. Bei so langen Statements erwähne ich häufig den Einsender nicht, aber in diesem Fall linke ich mal auf ein vergleichbares Statement von ihm, denn Kris macht das seit vielen, vielen Jahren und weiß, wovon er spricht. Das Verständnis der verschiedenen Herangehensweisen von Infrastruktur-Kram und Feature-Kram ist wichtig und es kann uns allen nur hilfreich sein, wenn wir es uns immer mal wieder vor Augen führen.Das ist ein großer Unterschied zu Libreoffice, das keine Infrastruktur ist und an neuen Best Cases (= neue Features) statt an seinen Worst Cases gemessen zu werden.
Infrastrukturentwickler verwenden also dieselben Sprachen, Tools, Unit-Tests, VCVSe und dergleichen mehr, arbeiten aber unter einem komplett anderen Wertesystem.
Wenn da einer auf der LKML ankommt und zeigt "Hier, neuer shiny code" (= neuer Best Case), dann wissen die schon, daß der aus einem anderen, falschen Universum ist. Infrastrukturentwickler wissen, daß Code auch immer Bugs/LoC hat, also eine Liability und kein Asset ist. Das kann man natürlich versuchen, solchen Personen immer wieder, und wieder, und wieder zu erklären, aber das kostet mehr Energie als es wert ist.
Man will in einer Infrastruktur auch nicht mehr Leute haben. Wenn wenn man da einmal genug Teilnehmer hat, daß das Projekt läuft, dann sind mehr Leute auch kein Asset, sondern eine Liability - und das gilt nicht nur für die LKML-Regulars oder Kernel-Committer, oder glibc-Developer, sondern auch für Leute, die Deine Gasleitungen oder Stromkabel warten, und sogar für Wikipedia Admins (sic!). Das ist ein ganz besonderer Menschenschlag, mit einer besonderen Arbeitsethik, die vollständig daraus stammt, daß die ihre Arbeit dann gut machen, wenn sie ihnen nicht gedankt wird und sie einfach niemand bemerkt.
Infrastrukturprojekte wollen nicht nur Deinen Code nicht, sondern auch Deine Mitarbeit nicht, weil sie - ausreichend Basis-Masse vorausgesetzt - beides nicht brauchen. Insbesondere können sie Dich nicht brauchen, wenn Du nicht diesen Infrastruktur-Mindset hast, weil Du sonst auch die Kritik und die Arbeitssituation unter einer Fail-Metrik wie sie bei Infrastuktur herrscht nicht aushältst.
Wenn man da als shiny bling bling Feature-Developer hin kommt, oder als eine 'Findet mich und meine Anliegen wichtig'-SJW-Mentalität, dann passiert eine Sarah Sharp.
Ich habe ja mein SSH schon vor einer Weile auf djb-Krypto umgestellt (hier hatte ich das beschrieben). Es ist leider auffallend schwierig, mit regulären Browsern djb-Krypto im TLS hinzukriegen. Firefox supported das noch nicht (warum eigentlich nicht?), Chrome supported es angeblich, aber ich kriege das nicht negotiated. OpenSSL kann es nicht (es gibt einen alten Patch, der aber nicht auf aktuelle Versionen passt), PolarSSL kann es nicht, BoringSSL kann es zwar, aber die Knalltüten haben das Buildsystem auf cmake umgestellt, und da krieg ich die dietlibc nicht reingepfriemelt. Das muss mir auch noch mal jemand erklären, wieso heutzutage jedes gammelige Hipsterprojekt sein eigenes Buildsystem braucht. Bei autoconf ist wenigstens dokumentiert, wie man da von außen eingreifen kann. Aber dieses cmake ist in der Beziehung nur für den Arsch, ich komm aus dem Fluchen gar nicht raus.
Und so bleibt mir im Moment nur LibreSSL, das kommt in der portablen Version mit autoconf und funktioniert mit dietlibc, und da taucht das auch in der Cipherliste auf, und wenn ich mit openssl s_client die Verbindung aufmache, kriege ich auch ECDHE-ECDSA-CHACHA20-POLY1305, aber mit Chrome? Kein Glück.
Und, mal unter uns, solange man da nicht von Hand noch eine ordentliche Kurve konfiguriert, ist das auch Mist. Von den Kurven, die OpenSSL unterstützt, scheint nur secp256k1 akzeptabel.
We show here how to put together an effective attack against CBC encryption as used by SSL 3.0, again assuming that the attacker can modify network transmissions between the client and the server. Unlike with the BEAST [BEAST] and Lucky 13 [Lucky13] attacks, there is no reasonable workaround. This leaves us with no secure SSL 3.0 cipher suites at all: to achieve secure encryption, SSL 3.0 must be avoided entirely.
Ein OpenSSL-Update gibt es noch nicht, und die OpenSSL-Webseite in der SSL-Version ist für mich auch gerade nicht erreichbar. LibreSSL hat gerade erst 2.1 released, ob die schon sicher ist weiß ich nicht.Wer sich jetzt Sorgen macht, SSL 3 abzuschalten: das SSL bei meinem Blog erlaubt seit April kein SSL 3 mehr. Es gab Null Beschwerden deshalb.
I do not have enough energy in my life to clean up two poorly written crypto code bases.
Immerhin signieren sie jetzt überhaupt, und zwar mit … signify. Nie gehört? Ich auch nicht. Das scheint was ad-hoc schnell selbst gehacktes zu sein. Hier ist das Argument dafür:$ wc -l *.cNun werdet ihr vielleicht sagen: hey, klingt gut, will ich haben. Wo ist der tarball?
29 crypto_api.c
143 mod_ed25519.c
327 mod_ge25519.c
806 signify.c
1305 totalSignify is 1305 *lines* of C code. and it's included in our development
platform. It is not that difficult to install, and
if you can't install it, you could always run OpenBSD in a vm to verify a
signature, it comes with openbsd.
Die Antwort: Es gibt keinen. Ich habe mir mal im Schweiße meines Angesichts die nötigen Teile aus dem OpenBSD-CVS herausgepopelt und in einen unter Linux bauenden Tarball getan. Mit dem ganzen Glue-Code sieht die Statistik schon mal gleich ganz anders aus, da sind wir dann plötzlich bei knapp 8000 Codezeilen (plus libc, natürlich).
Das baut bei mir, und ich kann damit die LibreSSL-Distribution verifizieren. Immerhin. Das ist aber natürlich immer noch voll für den Fuß, weil der public key von deren Signatur auf dem selben FTP-Server liegt wie die Daten. Wenn jemand den Tarball manipulieren kann, kann er also auch einen anderen pubkey daneben legen und keiner merkt was. Bei GnuPG gibt es ja wenigstens das Web of Trust.
Nun habe ich mir für meine SSL-Library gedacht, dass ich nur auf Systemen laufen werde, bei denen es /dev/urandom oder Äquivalent gibt, und nicht versuchen werde, da selber irgendwelche Entropie-Fummeleien zu machen. Das kann eigentlich nur nach hinten losgehen.
Aaaaaaber. Ein Kumpel von mir macht SSL auf einem Rechner, der nicht am Netz hängt, und eine Smartcard mit Hardware-RNG hat. Es gibt Smartcards mit Hardware-Zufall und einem kleinen ARM drauf. Habt ihr mal darüber nachgedacht, woher der Kernel den Zufall in /dev/urandom nimmt? Dafür nimmt man so Dinge wie das Timing zwischen Netzwerkpaketen und die Rotationslatenz von Festplatten. Timing von Tastatur- und Mauseingaben. Gibt es bei Smartcards alles nicht. Auf Smartphones gibt es Eingabegeräte aber keine Festplatten und bei den Netzwerkpaketen musst du davon ausgehen, dass sie ein Angreifer schickt, um deinen Zufall vorhersagen zu können.
Das ist ein echtes Problem in der Praxis. Gerade wenn ein Gerät frisch gebootet wurde, und die ganzen Krypto-Dienste hochfahren und Zufall für temporäre Schlüssel haben wollen. In solchen Fällen ist es wichtig, dass man den Zufallszahlengenerator irgendwie mit echtem Zufall seeden kann. Auch auf Servern mit SSD ist das ein Problem, wenn da keine Eingaben per Maus und Tastatur kommen.
Unter Linux kann man dafür einfach Daten nach /dev/random schreiben. Unter Windows gibt es zwar auch einen RNG in CryptoAPI, aber es gibt keinen Weg, da Zufall reinzuseeden. Die Sache mit dem Bildschirm-Auslesen ist natürlich echt ein Kracher. Aber da einfach die Möglichkeit wegzunehmen, externen Zufall reinzupipen, das macht LibreSSL für viele Anwendungen kaputt.
Übrigens, sowas wie ~/.rng kommt als Idee daher, dass man beim Runterfahren Entropie aus dem Pool ins Filesystem schreibt, damit man nach dem nächsten Hochfahren gute Entropie hat, wenn man ihn braucht. Das ist nicht per se eine doofe Idee.
Was ich sagen will: LibreSSL schießt sich hier gerade ziemlich massiv in den Fuß. Das sollte man dann auch erst mal ein paar Jahre aufhängen und reifen lassen, bevor man das einsetzen kann. Schade eigentlich.
Update: Mich weist gerade jemand darauf hin, dass das unter Windows doch auch geht.
Damit war nicht OpenSSL gemeint, sondern sowas wie X, perl, gcc. Aber OpenSSL fiel auch darunter, in dem Sinne, dass ich da eh noch andere Vorbehalte für einen Audit hatte. Und diese Policy hat dann dazu geführt, dass ich da auch nicht mal oberflächlich reingucken wollte.
Da ich angesichts aktueller Entwicklungen eh nicht gut schlafen kann mit OpenSSL gerade, habe ich mich entschieden, doch mal kurz einen Blick zu werfen.
Ich bin, gelinde gesagt, entsetzt. Schon die OpenBSD-LibreSSL-CVS-Checkin-Kommentare haben ja tief blicken lassen.
Es gibt so ein paar Kriterien, an denen ich bei C-Code meinen ersten Eindruck festmache. Das erste Kriterium ist, dass Längen und Offsets immer unsigned sein müssen, und vom Typ size_t. Früher hätte ich gesagt: unsigned long ist auch OK. Aber es gibt Plattformen, auf denen long 32-bit aber size_t 64-bit ist. 64-bit Windows z.B. Daher muss es size_t sein, nicht unsigned long. Und schon gar nicht long. Hier ist, was OpenSSL macht:
static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)Hier fallen ja schonmal als erstes die intuitiven Variablennamen auf. Da weiß man doch sofort, was gemeint ist! Ich kläre mal auf: Diese Routine soll einen ASN.1 DER Längenwert parsen. Das Encoding davon ist: Wenn das erste Byte das höchste Bit gesetzt hat, dann sind die unteren 7 Bits die Länge in Bytes für die Länge, die dahinter in big endian folgt. Wenn das erste Byte das höchste Bit nicht gesetzt hat, dann sind die unteren 7 Bits der Wert. Weil X.509 DER benutzt, gibt es zusätzlich noch die Regel, dass alle Längen minimal encoded sein müssen. Beispiele:
05 - Wert 5Meinem aktuellen Verständnis nach kann indefinite length bei X.509 nicht vorkommen, und ich unterstütze den Fall in meinen ASN.1-Routinen im Moment auch nicht sondern liefere einen Fehlerwert zurück. OpenSSL supported das. Möglicherweise übersehe ich da was. Wo ich aber nichts übersehe: OpenSSL prüft an keiner Stelle, dass das Encoding minimal ist. Der Effekt ist, dass man das identische Zertifikat auf mehrere Arten kodieren kann, und damit möglicherweise Angriffsfläche auf Krypto-Verfahren schaffen kann. Überhaupt sind Unterschiede zwischen Parsern immer doof, Differentiale will man an solchen Stellen vermeiden. Das ist jetzt kein "OMG RUN FOR THE HILLS"-Moment, aber wenn man schon eine zentrale Library macht für sowas, dann doch um da penibel solche Sachen abzufangen, damit die Leute das nicht alle von Hand machen und vergessen.
7f - Wert 127
81 01 - Ungültig, da nicht minimal encoded; wäre sonst 1
82 00 23 - Ungültig, da nicht minimal encoded; wäre sonst 35
82 12 34 - Wert 4660 (0x1234)
89 11 11 11 11 11 11 11 11 11 - Ungültig, da der 9-Byte-Wert nicht in einen Integer passt
0x80 - Sonderfall, "indefinite length".
Aber unabhängig davon. pp ist der Quell-Zeiger (das const ist ein gutes Zeichen, das wäre Kriterium 2 für das Erkennen von schlechtem Code gewesen). inf wird auf 1 gesetzt, wenn indefinite length encoding reinkommt. Ich finde, das hätte man direkt zurückweisen sollen. Indefinite length encoding funktioniert so, dass man am Anfang sagt, man weiß nicht, wie groß die Daten werden, die jetzt kommen, und dann schickt man halt so viele Daten wie halt kommen und dann zwei Null-Bytes. Ganz schlechte Idee, und habe ich in der Praxis auch noch nie im Einsatz beobachten können. Das ist ja gerade der Grund, wieso man ASN.1 DER einsetzt, damit man vorher weiß, wieviele Daten jetzt kommen werden. Und im Übrigen siehe oben zu den Parser-Differenzen. Das will man vermeiden.
Aber der eigentliche Punkt, auf den ich die ganze Zeit hinauswill: die Länge ist ein long. Das ist ein ganz schlechtes Zeichen. Die Routine versucht, das Schlimmste zu verhindern, indem sie als unsigned parsed und dann einen Fehler meldet, wenn der Wert größer als LONG_MAX ist. Und in der Tat, wenn sie das nicht gemacht hätte, hätte es im String-Parsing direkt einen schönen Buffer Overflow gegeben.
Ich habe jetzt jedenfalls ein schlechtes Gefühl bei OpenSSL und werde glaube ich erstmal die ASN.1-Routinen von PolarSSL auditieren, damit ich einen Fallback habe, wenn ich die ganzen Atommüllablagerungen in den Fracking-Schächten bei OpenSSL finde.
Update: Oh Graus, ich erfahre gerade, dass ich X.509 die ganze Zeit falsch verstanden hatte. Ich hatte das so verstanden, dass X.509 immer DER Encoding nimmt. Denn, mit Verlaub, alles andere ergibt auch gar keinen Sinn. Man will das ja in digitalen Signaturen verwenden. DER ist eine Teilmenge von BER, die genau den Zweck und die Daseinsberechtigung hat, dass man alles nur auf genau eine wohldefinierte Art kodieren kann. Begründung: Das braucht man so für digitale Signaturen. Und jetzt erfahre ich gerade, dass X.509 gar nicht DER sondern BER benutzt! Man soll das als Implementation anscheinend als BER parsen, dann soll man das als DER neu kodieren und dann die Signaturberechnungen machen!? Das kann ja wohl nicht wahr sein! Dann hätte OpenSSL Recht mit ihrem Code. Heilige Scheiße, wer denkt sich denn solche Standards aus!? In der Praxis habe ich noch nie was anderes als DER-Encoding gesehen. In meiner SSL-Library werde ich jedenfalls gleich beim parsen alles rejecten, das nicht DER ist.
Update: Interessanterweise macht OpenSSL es auch falsch, wenn BER Absicht ist.
173 if (i > sizeof(long))
174 return 0;
Java hat uns den RAM billig gemacht. Computerspiele haben uns Grafikkarten schnell und billig gemacht. Pornographie hat uns Internet schnell und billig gemacht. Und Antiviren machen uns die Rechner schnell und billig. Ich saß da an einem Arbeitsplatzrechner, der vom Kunden zur Verfügung gestellt wurde. Da lief natürlich auch ein Antivirus drauf. Und ich habe da, weil ich ja nichts neues starte oder runterlade, die ganzen Komponenten deaktiviert, die normalerweise so nebenbei mitlaufen, und alle Dateien scannen, die von irgendeinem Prozess geöffnet werden. Stellt sich raus: DAS war es, wieso Office bei mir so flutschte. Bei meinem Nachbarn schnarchte das wie gewohnt vor sich hin. Der hatte das nicht ausgeschaltet.
In diesem Sinne: Antiviren sind natürlich immer noch Schlangenöl und machen die Menschen unsicherer statt sicherer, aber wir sollten ihnen trotzdem dankbar sein, weil sie dafür gesorgt haben, dass andere Software schneller wird, weil es sonst überhaupt nicht ertragbar wäre.
Ich würde sogar so weit gehen, für Linux Antiviren zu fordern. Das ist ein echter Wettbewerbsnachteil, den Linux-Softwareentwicklung da hat. Die Entwickler sehen keinen Optimierungsbedarf, weil das bei ihnen flutscht. Wenn man nicht gerade Old School seine Dokumente mit TeX oder troff schreibt, ist der Performance-Zustand der Office-Suiten unter Unix geradezu beschämend. Und die ganzen Sprallos von Freedesktop und co kommen ja auch jedes Jahr mit weiteren Indirektionsschichten mit XML und endloser Redundanz, weil sie es können! Wenn da noch ein paar Antiviren das System auf C64-Niveau verlangsamen würden, dann würden diese Leute effizienteren Code schreiben.