Skip to content
This repository was archived by the owner on Aug 18, 2020. It is now read-only.

Commit d17c915

Browse files
committed
[CO-389] Patch x509 parseSAN function to encode IP to valid bytes
Turns out that we can't use the 'encode' function from Net.IP as it generates invalid encoding for x509. I left a NOTE explaining what's going on such that next readers will know what's going on.
1 parent c68ec9c commit d17c915

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

x509/cardano-sl-x509.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ library
3434
, filepath
3535
, hourglass
3636
, ip
37+
, network-transport
3738
, optparse-applicative
3839
, text
3940
, universum

x509/src/Data/X509/Extra.hs

+30-4
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,19 @@ import Data.X509.CertificateStore (CertificateStore,
4747
makeCertificateStore)
4848
import Data.X509.Validation
4949
import Net.IP (IP)
50+
import Net.IPv4 (IPv4 (..))
51+
import Net.IPv6 (IPv6 (..))
52+
import Network.Transport.Internal (encodeWord32)
5053

5154
import qualified Crypto.PubKey.RSA.Types as RSA
5255
import qualified Data.ByteString as BS
5356
import qualified Data.ByteString.Base64 as Base64
57+
import qualified Data.ByteString.Builder as BS
5458
import qualified Data.ByteString.Char8 as B8
5559
import qualified Data.ByteString.Lazy as BL
5660
import qualified Data.Text as T
5761
import qualified Data.Text.Encoding as T
5862
import qualified Net.IP as IP
59-
import qualified Net.IPv4 as IPv4
60-
import qualified Net.IPv6 as IPv6
6163

6264

6365
--
@@ -175,10 +177,34 @@ parseSAN :: String -> AltName
175177
parseSAN name =
176178
case IP.decode (toText name) of
177179
Just ip ->
178-
AltNameIP . T.encodeUtf8 $ IP.case_ IPv4.encode IPv6.encode ip
180+
AltNameIP $ IP.case_ ipv4ToBS ipv6ToBS ip
179181

180182
Nothing ->
181183
AltNameDNS name
184+
where
185+
-- NOTE
186+
-- Here, we define custom encoding functions and aren't using the ones
187+
-- defined in `Net.IP`, `Net.IPv4` or `Net.IPv6`.
188+
-- Those methods lead to invalid encodings for the underlying x509 certificates.
189+
--
190+
-- From the RFC 3779 (https://datatracker.ietf.org/doc/rfc3779):
191+
--
192+
-- > IP v4 address - a 32-bit identifier written as four decimal numbers,
193+
-- > each in the range 0 to 255, separated by a ".". 10.5.0.5 is an
194+
-- > example of an IPv4 address.
195+
-- >
196+
-- > IP v6 address - a 128-bit identifier written as eight hexadecimal
197+
-- > quantities, each in the range 0 to ffff, separated by a ":".
198+
-- > 2001:0:200:3:0:0:0:1 is an example of an IPv6 address. One string
199+
-- > of :0: fields may be replaced by "::", thus 2001:0:200:3::1
200+
-- > represents the same address as the immediately preceding example.
201+
ipv4ToBS :: IPv4 -> ByteString
202+
ipv4ToBS (IPv4 bytes) =
203+
encodeWord32 bytes
204+
205+
ipv6ToBS :: IPv6 -> ByteString
206+
ipv6ToBS (IPv6 a b) =
207+
BL.toStrict $ BS.toLazyByteString (BS.word64BE a <> BS.word64BE b)
182208

183209

184210
--
@@ -282,7 +308,7 @@ validateCertificateIP ip cert =
282308
toCommonName =
283309
asn1CharacterToString >=> (ipFromBytes . B8.pack)
284310
in
285-
if any (== ip) (maybeToList commonName ++ altNames) then
311+
if ip `elem` (maybeToList commonName ++ altNames) then
286312
[]
287313
else
288314
[NameMismatch $ T.unpack $ IP.encode ip]

0 commit comments

Comments
 (0)