Monday, July 30, 2018

A Fairy Tale of an Old Music Box

One of things I really like doing in my spare time is playing the piano we bought recently. I also decided to check whether there is some decent score writing software out there and I was really surprised to find that the software not only gets much, much better over years but also that there are even some free yet advanced apps like the MuseScore.

Anyway, this looks like my chance to write down few ideas I had on my mind for all these years since I finished my music education. And since sharing is one of nice features of the software, please enjoy one of my compositions, the first one I wrote down with MuseScore, A Fairy Tale of an Old Music Box.

A Fairy Tale of an Old Music Box

Friday, July 13, 2018

.NET 4.7.1 (and higher) no longer supports SHA1 in SignedXml

There are plenty of subtle changes between .NET 4.7.0 (and lower) and .NET 4.7.1, however one of the changes hurt us badly. It looks like the SignedXml no longer supports SHA1 as the hashing method.

What it causes is the

System.Security.Cryptography.CryptographicException : Invalid algorithm specified
...
     at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 cbHash, ObjectHandleOnStack retSignature)
     at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash)
     at System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash)
     at System.Security.Cryptography.Xml.SignedXml.ComputeSignature()

The resolution is to put an additional section in the app's config file that switches the use of insecure hashes on:

  <runtime>
    <AppContextSwitchOverrides value="Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms=true;
                                         Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms=true" />
  </runtime>

If these switches seem to be ignored (we observed this in web apps where this was put in the web.config rather than an app.config, simply replace it with the code that you put in the global app class in the Application_Start:

protected void Application_Start(object sender, EventArgs e)
{
   ...
   AppContext.SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true);
   AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);
}

Monday, July 2, 2018

Integracja z ePUAP - dzień bez zmiany dniem straconym

Przed weekendem 30-06/01-07 blogowałem o zmianie na środowisku testowym ePUAP, przywracającym SHA1 w trybie wymuszenia (SHA256 przestało być obsługiwane) w konstruowaniu sygnatur WS-* w żądaniach do usług integracyjnych. Napisałem też że mam nadzieję na uporządkowanie sytuacji.

Cóż, sytuacja uporządkowała się o tyle że dziś (02-07) od południa na środowisku testowym ePUAP (int.pz.gov.pl) stoi kolejna wersja, która znów wymusza SHA256 i nie obsługuje SHA1.

Pytanie retoryczne: jak długo jeszcze może trwać ten kołowrotek i jak długo poczekamy na wersję która obsłuży oba rodzaje funkcji skrótu?

Friday, June 29, 2018

Integracja z ePUAP - zamiana powrotna SHA256 na SHA1

Dziś czyli w piątek, 29 czerwca 2018, około godziny 14-tej, środowisko testowe ePUAP zostało ponownie zaktualizowane. Tym razem do wersji która nie obsługuje całkowicie algorytmu SHA256, zamiast tego wraca do sytuacji w której w komunikacji wymagane jest SHA1.

Ta zmiana ociera się o skandal i sprawia wrażenie że COI nie panuje nad sytuacją. Byłoby zrozumiałe, gdyby nowa wersja przywracała wsparcie dla SHA1 ale poprawnie obsługiwała oba, SHA1 i SHA256. Natomiast udostępnienie wersji która na działającym kodzie wykorzystującym SHA256 zwraca z serwera wyjątki bezpieczeństwa, na które lekarstwem jest przywrócenie SHA1 po stronie integrowanej aplikacji, bardzo źle świadczy o kulturze wytwarzanego kodu i wsparcia integratorów.

Być może jest to tylko niedopatrzenie i sytuacja wróci do normy (=będą obsługiwane oba rodzaje funkcji skrótu) w niedługim czasie, ale zamieszanie jakie powoduje COI nieprzemyślaną jak widać do końca migracją, powoduje perturbacje po stronie integratorów.

Wednesday, June 13, 2018

Integracja z ePUAP - zmiana SHA-1 na SHA-256

Środowisko testowe ePUAP zostało właśnie dostosowane do zmian wymuszonych Ustawą o usługach zaufania oraz identyfikacji elektronicznej z września 2016, która w art. 137 mówi:
Do dnia 1 lipca 2018 r. do składania zaawansowanych podpisów elektronicznych lub zaawansowanych pieczęci elektronicznych można stosować funkcję skrótu SHA-1, chyba że wymagania techniczne wynikające z aktów wykonawczych wydanych na podstawie rozporządzenia 910/2014 wyłączą możliwość stosowania tej funkcji skrótu.
Istotnie, wdrożona na środowisku testowym zmiana powoduje zwracanie statusu A security error was encountered when verifying the message przy komunikacji z dowolną usługą.
Komunikat błędu nie jest może bardzo przydatny w diagnozie problemu, niemniej warto odnotować, że faktycznie chodzi o konieczność wymiany SHA-1 na SHA-256, co jest szalenie istotne w kontekście generowania podpisów XMLDsig w komunikacji z usługami - przynajmniej w .NET, domyślnie dostawca podpisów obiektu SignedXml wybiera SHA-1, ponieważ tak podpowiada sygnatura certyfikatu. A nadpisanie tej domyślnej konwencji w taki sposób żeby do wyliczenia sygnatury został użyty algorytm SHA-256 wcale nie jest takie oczywiste. A skąd wiadomo że akurat SHA-256? Cóż, na środowisku testowym zaktualizowano również dokumentację dla integratorów i tam w wyciągach z przykładowych żądań i odpowiedzi systemu pojawia się właśnie ten algorytm, wszędzie tam gdzie we wcześniejszych wersjach widniał sha1.
Niewykluczone że z początkiem lipca czeka nas wysyp "awarii" systemów zewnętrznych zintegrowanych z ePUAP, które z różnych powodów nie zaimplementują tej zmiany. W kontekście wczorajszej (2018-06-12) dużej awarii e-usług - być może ta awaria i planowana zmiana mają jakiś związek.

Friday, April 20, 2018

Retaining document relative links when copying from HTML to Word

We have an automated document generation tool that creates a HTML documentation of a given database. The generated HTML structure uses relative links between elements, this is very convenient for users who browse the documentation.
For example, somewhere in the document a database table is documented
<h2>Table <a name="TheTable">TheTable</a></h2>
and somewhere else the table is referenced
<a href="#TheTable>TheTable</a>
Let's create a simplest HTML as an example
<html>
<body>

<div>
This is a reference to <a href="#TheTable">TheTable</a>.
</div>

<div>
This is the definition of <a name="TheTable">TheTable</a>
</div>


</body>
</html>
and copy/paste it to Word
Take a closer look at what happened with the relative link - it has been pasted as a link to the source HTML document! That's kind of a disaster, I definitely don't want my relative links to suddenly become absolute and what's worse - point from Word to an external, source HTML document!
This inconvenience can be fixed manually, I can just right-click at the link, edit its properties and change the link type from existing file or a web page to a bookmark in this document:
however, manually fixing hundreds of links sounds like a daunting task.
Fortunately, this can be fixed automatically, with a local VBA script in the Word document that basically creates another link in the very same range of the document but with empty Address property - by multiple trials and errors I've determined this is the only difference between external and internal, relative links:
Do follow these steps to have your links fixed then:
  1. Copy/paste your HTML into Word
  2. alt+F11 to open VBA editor
  3. Double click ThisDocument to open a code editor for scripts in current document
  4. Paste the script into the editor window
    Sub FixHyperlinks()
    
    Dim h As Hyperlink
    For Each h In ActiveDocument.Hyperlinks
    
        ActiveDocument.Hyperlinks.Add h.Range, "", h.SubAddress
    
    Next h
    End Sub
    
  5. Place cursor somewhere inside the script and hit F5 (or click the green triangle) to run the macro
Relative links now correctly point to elements in the very same document, even exporting to PDF retains the correct behavior.

Monday, April 9, 2018

Extending Generator prototype to get LINQ-like experience in Javascript

Generator functions let us write iterators in a very concise way. Take a simple example:

function* range(n,m) {
    for ( var i=n; i<m; i++ ) {
        yield i;
    }
}
This lets me write
for ( var e of range(0,10) ) {
   console.log( e );
}
to get an iterator that returns numbers from 0 to 9.

An interesting question has been asked at the SO - can such generators be extended with extension methods that would work in a similar way C#'s LINQ works, where one can chain filtering, groupping or sorting operators.

My suggestion there was to extend the Generator prototype, which is technically possible and could possibly be surprising as the Generator literal doesn't resolve at the top-level. A trick here is to first resolve it manually and only then extend the prototype.

var Generator = Object.getPrototypeOf( function*() {});

Generator.prototype.filter = function*( predicate ) {
    for ( var e of this ) {
        if ( predicate(e) )
            yield e;
    }
}
This leads to following convention:
for ( var e of 
    range(0,10)
        .filter( x => x<8 )
        .filter( x => x > 2 ) ) {
    console.log(e);
}
Other operators can be added in a similar way.