Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
T
Titanium-Web-Proxy
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Titanium-Web-Proxy
Commits
82f88814
Commit
82f88814
authored
Jun 27, 2017
by
Honfika
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Parse ssl extensions
parent
c8338bfe
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
445 additions
and
18 deletions
+445
-18
CustomBufferedPeekStream.cs
Titanium.Web.Proxy/Helpers/CustomBufferedPeekStream.cs
+2
-1
ConnectRequest.cs
Titanium.Web.Proxy/Http/ConnectRequest.cs
+15
-0
HttpsTools.cs
Titanium.Web.Proxy/Http/HttpsTools.cs
+428
-17
No files found.
Titanium.Web.Proxy/Helpers/CustomBufferedPeekStream.cs
View file @
82f88814
...
...
@@ -17,10 +17,11 @@ namespace Titanium.Web.Proxy.Helpers
position
=
startPosition
;
}
public
int
Available
=>
baseStream
.
Available
-
position
;
public
async
Task
<
bool
>
EnsureBufferLength
(
int
length
)
{
var
val
=
await
baseStream
.
PeekByteAsync
(
length
-
1
);
var
val
=
await
baseStream
.
PeekByteAsync
(
position
+
length
-
1
);
return
val
!=
-
1
;
}
...
...
Titanium.Web.Proxy/Http/ConnectRequest.cs
View file @
82f88814
...
...
@@ -36,6 +36,12 @@ namespace Titanium.Web.Proxy.Http
public
byte
[]
SessionId
{
get
;
set
;
}
public
byte
[]
CiphersData
{
get
;
set
;
}
public
byte
[]
CompressionData
{
get
;
set
;
}
public
List
<
Extension
>
Extensions
{
get
;
set
;
}
private
static
string
SslVersionToString
(
int
major
,
int
minor
)
{
string
str
=
"Unknown"
;
...
...
@@ -69,6 +75,15 @@ namespace Titanium.Web.Proxy.Http
sb
.
AppendLine
(
$"\"Time\":
{
Time
}
"
);
sb
.
AppendLine
(
$"SessionID:
{
string
.
Join
(
" "
,
SessionId
.
Select
(
x
=>
x
.
ToString
(
"X2"
)))}
"
);
if
(
Extensions
!=
null
)
{
sb
.
AppendLine
(
"Extensions:"
);
foreach
(
var
extension
in
Extensions
)
{
sb
.
AppendLine
(
$"
{
extension
.
Name
}
:
{
extension
.
Data
}
"
);
}
}
return
sb
.
ToString
();
}
}
...
...
Titanium.Web.Proxy/Http/HttpsTools.cs
View file @
82f88814
...
...
@@ -45,8 +45,8 @@ namespace Titanium.Web.Proxy.Http
var
peekStream
=
new
CustomBufferedPeekStream
(
clientStream
,
1
);
//should contain at least 43 bytes
int
requiredLength
=
43
;
// 2 version + 2 length + 1 type + 3 length(?) + 2 version + 32 random + 1 sessionid length
if
(!
await
peekStream
.
EnsureBufferLength
(
requiredLength
))
// 2 version + 2 length + 1 type + 3 length(?) + 2 version + 32 random + 1 sessionid length
if
(!
await
peekStream
.
EnsureBufferLength
(
43
))
{
return
false
;
}
...
...
@@ -56,7 +56,7 @@ namespace Titanium.Web.Proxy.Http
int
minorVersion
=
peekStream
.
ReadByte
();
int
length
=
peekStream
.
ReadInt16
();
if
(
peekStream
.
ReadByte
()
!=
0x01
)
{
// should be ClientHello
...
...
@@ -71,8 +71,8 @@ namespace Titanium.Web.Proxy.Http
byte
[]
random
=
peekStream
.
ReadBytes
(
32
);
length
=
peekStream
.
ReadByte
();
requiredLength
+=
length
+
2
;
// sessionid + 2 d
ata length
if
(!
await
peekStream
.
EnsureBufferLength
(
requiredLength
))
// sessionid + 2 ciphersD
ata length
if
(!
await
peekStream
.
EnsureBufferLength
(
length
+
2
))
{
return
false
;
}
...
...
@@ -81,13 +81,13 @@ namespace Titanium.Web.Proxy.Http
length
=
peekStream
.
ReadInt16
();
requiredLength
+=
length
+
1
;
// data + data2
length
if
(!
await
peekStream
.
EnsureBufferLength
(
requiredLength
))
// ciphersData + compressionData
length
if
(!
await
peekStream
.
EnsureBufferLength
(
length
+
1
))
{
return
false
;
}
byte
[]
d
ata
=
peekStream
.
ReadBytes
(
length
);
byte
[]
ciphersD
ata
=
peekStream
.
ReadBytes
(
length
);
length
=
peekStream
.
ReadByte
();
if
(
length
<
1
)
...
...
@@ -95,26 +95,31 @@ namespace Titanium.Web.Proxy.Http
return
false
;
}
requiredLength
+=
length
;
// data2
if
(!
await
peekStream
.
EnsureBufferLength
(
requiredL
ength
))
// compressionData
if
(!
await
peekStream
.
EnsureBufferLength
(
l
ength
))
{
return
false
;
}
byte
[]
data2
=
peekStream
.
ReadBytes
(
length
);
byte
[]
compressionData
=
peekStream
.
ReadBytes
(
length
);
byte
[]
data3
=
null
;
List
<
Extension
>
extensions
=
null
;
if
(
majorVersion
>
3
||
majorVersion
==
3
&&
minorVersion
>=
1
)
{
requiredLength
+=
2
;
if
(
await
peekStream
.
EnsureBufferLength
(
requiredLength
))
if
(
await
peekStream
.
EnsureBufferLength
(
2
))
{
length
=
peekStream
.
ReadInt16
();
requiredLength
+=
length
;
if
(
await
peekStream
.
EnsureBufferLength
(
requiredLength
))
if
(
await
peekStream
.
EnsureBufferLength
(
length
))
{
data3
=
peekStream
.
ReadBytes
(
length
);
extensions
=
new
List
<
Extension
>();
while
(
peekStream
.
Available
>
3
)
{
int
id
=
peekStream
.
ReadInt16
();
length
=
peekStream
.
ReadInt16
();
byte
[]
data
=
peekStream
.
ReadBytes
(
length
);
extensions
.
Add
(
GetExtension
(
id
,
data
));
}
}
}
}
...
...
@@ -125,6 +130,9 @@ namespace Titanium.Web.Proxy.Http
MinorVersion
=
minorVersion
,
Random
=
random
,
SessionId
=
sessionId
,
CiphersData
=
ciphersData
,
CompressionData
=
compressionData
,
Extensions
=
extensions
,
};
return
true
;
...
...
@@ -132,5 +140,408 @@ namespace Titanium.Web.Proxy.Http
return
false
;
}
private
static
Extension
GetExtension
(
int
value
,
byte
[]
data
)
{
string
name
=
GetExtensionName
(
value
);
string
dataStr
=
GetExtensionData
(
value
,
data
);
return
new
Extension
(
value
,
name
,
dataStr
);
}
private
static
string
GetExtensionData
(
int
value
,
byte
[]
data
)
{
//https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
switch
(
value
)
{
case
0
:
var
stringBuilder
=
new
StringBuilder
();
int
index
=
2
;
while
(
index
<
data
.
Length
)
{
int
nameType
=
data
[
index
];
int
count
=
(
data
[
index
+
1
]
<<
8
)
+
data
[
index
+
2
];
string
str
=
Encoding
.
ASCII
.
GetString
(
data
,
index
+
3
,
count
);
if
(
nameType
==
0
)
{
stringBuilder
.
AppendFormat
(
"{0}{1}"
,
stringBuilder
.
Length
>
1
?
"; "
:
string
.
Empty
,
str
);
}
index
+=
3
+
count
;
}
return
stringBuilder
.
ToString
();
case
5
:
if
(
data
.
Length
==
5
&&
data
[
0
]
==
1
&&
data
[
1
]
==
0
&&
data
[
2
]
==
0
&&
data
[
3
]
==
0
&&
data
[
4
]
==
0
)
{
return
"OCSP - Implicit Responder"
;
}
return
ByteArrayToString
(
data
);
case
10
:
return
GetSupportedGroup
(
data
);
case
11
:
return
GetEcPointFormats
(
data
);
case
13
:
return
GetSignatureAlgorithms
(
data
);
case
16
:
return
GetApplicationLayerProtocolNegotiation
(
data
);
case
35655
:
return
$"
{
data
.
Length
}
bytes"
;
default
:
return
ByteArrayToString
(
data
);
}
}
private
static
string
GetSupportedGroup
(
byte
[]
data
)
{
//https://datatracker.ietf.org/doc/draft-ietf-tls-rfc4492bis/?include_text=1
List
<
string
>
list
=
new
List
<
string
>();
if
(
data
.
Length
<
2
)
{
return
string
.
Empty
;
}
int
i
=
2
;
while
(
i
<
data
.
Length
-
1
)
{
int
namedCurve
=
(
data
[
i
]
<<
8
)
+
data
[
i
+
1
];
switch
(
namedCurve
)
{
case
1
:
list
.
Add
(
"sect163k1 [0x1]"
);
//deprecated
break
;
case
2
:
list
.
Add
(
"sect163r1 [0x2]"
);
//deprecated
break
;
case
3
:
list
.
Add
(
"sect163r2 [0x3]"
);
//deprecated
break
;
case
4
:
list
.
Add
(
"sect193r1 [0x4]"
);
//deprecated
break
;
case
5
:
list
.
Add
(
"sect193r2 [0x5]"
);
//deprecated
break
;
case
6
:
list
.
Add
(
"sect233k1 [0x6]"
);
//deprecated
break
;
case
7
:
list
.
Add
(
"sect233r1 [0x7]"
);
//deprecated
break
;
case
8
:
list
.
Add
(
"sect239k1 [0x8]"
);
//deprecated
break
;
case
9
:
list
.
Add
(
"sect283k1 [0x9]"
);
//deprecated
break
;
case
10
:
list
.
Add
(
"sect283r1 [0xA]"
);
//deprecated
break
;
case
11
:
list
.
Add
(
"sect409k1 [0xB]"
);
//deprecated
break
;
case
12
:
list
.
Add
(
"sect409r1 [0xC]"
);
//deprecated
break
;
case
13
:
list
.
Add
(
"sect571k1 [0xD]"
);
//deprecated
break
;
case
14
:
list
.
Add
(
"sect571r1 [0xE]"
);
//deprecated
break
;
case
15
:
list
.
Add
(
"secp160k1 [0xF]"
);
//deprecated
break
;
case
16
:
list
.
Add
(
"secp160r1 [0x10]"
);
//deprecated
break
;
case
17
:
list
.
Add
(
"secp160r2 [0x11]"
);
//deprecated
break
;
case
18
:
list
.
Add
(
"secp192k1 [0x12]"
);
//deprecated
break
;
case
19
:
list
.
Add
(
"secp192r1 [0x13]"
);
//deprecated
break
;
case
20
:
list
.
Add
(
"secp224k1 [0x14]"
);
//deprecated
break
;
case
21
:
list
.
Add
(
"secp224r1 [0x15]"
);
//deprecated
break
;
case
22
:
list
.
Add
(
"secp256k1 [0x16]"
);
//deprecated
break
;
case
23
:
list
.
Add
(
"secp256r1 [0x17]"
);
break
;
case
24
:
list
.
Add
(
"secp384r1 [0x18]"
);
break
;
case
25
:
list
.
Add
(
"secp521r1 [0x19]"
);
break
;
case
26
:
list
.
Add
(
"brainpoolP256r1 [0x1A]"
);
break
;
case
27
:
list
.
Add
(
"brainpoolP384r1 [0x1B]"
);
break
;
case
28
:
list
.
Add
(
"brainpoolP512r1 [0x1C]"
);
break
;
case
29
:
list
.
Add
(
"x25519 [0x1D]"
);
break
;
case
30
:
list
.
Add
(
"x448 [0x1E]"
);
break
;
case
256
:
list
.
Add
(
"ffdhe2048 [0x0100]"
);
break
;
case
257
:
list
.
Add
(
"ffdhe3072 [0x0101]"
);
break
;
case
258
:
list
.
Add
(
"ffdhe4096 [0x0102]"
);
break
;
case
259
:
list
.
Add
(
"ffdhe6144 [0x0103]"
);
break
;
case
260
:
list
.
Add
(
"ffdhe8192 [0x0104]"
);
break
;
case
65281
:
list
.
Add
(
"arbitrary_explicit_prime_curves [0xFF01]"
);
//deprecated
break
;
case
65282
:
list
.
Add
(
"arbitrary_explicit_char2_curves [0xFF02]"
);
//deprecated
break
;
default
:
list
.
Add
(
$"unknown [0x
{
namedCurve
:
X4
}
]"
);
break
;
}
i
+=
2
;
}
return
string
.
Join
(
", "
,
list
.
ToArray
());
}
private
static
string
GetEcPointFormats
(
byte
[]
data
)
{
List
<
string
>
list
=
new
List
<
string
>();
if
(
data
.
Length
<
1
)
{
return
string
.
Empty
;
}
int
i
=
1
;
while
(
i
<
data
.
Length
)
{
switch
(
data
[
i
])
{
case
0
:
list
.
Add
(
"uncompressed [0x0]"
);
break
;
case
1
:
list
.
Add
(
"ansiX962_compressed_prime [0x1]"
);
break
;
case
2
:
list
.
Add
(
"ansiX962_compressed_char2 [0x2]"
);
break
;
default
:
list
.
Add
(
$"unknown [0x
{
data
[
i
]:
X2
}
]"
);
break
;
}
i
+=
2
;
}
return
string
.
Join
(
", "
,
list
.
ToArray
());
}
private
static
string
GetSignatureAlgorithms
(
byte
[]
data
)
{
// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml
int
num
=
(
data
[
0
]
<<
8
)
+
data
[
1
];
var
sb
=
new
StringBuilder
();
int
index
=
2
;
while
(
index
<
num
+
2
)
{
switch
(
data
[
index
])
{
case
0
:
sb
.
Append
(
"none"
);
break
;
case
1
:
sb
.
Append
(
"md5"
);
break
;
case
2
:
sb
.
Append
(
"sha1"
);
break
;
case
3
:
sb
.
Append
(
"sha224"
);
break
;
case
4
:
sb
.
Append
(
"sha256"
);
break
;
case
5
:
sb
.
Append
(
"sha384"
);
break
;
case
6
:
sb
.
Append
(
"sha512"
);
break
;
case
8
:
sb
.
Append
(
"Intrinsic"
);
break
;
default
:
sb
.
AppendFormat
(
"Unknown[0x{0:X2}]"
,
data
[
index
]);
break
;
}
sb
.
AppendFormat
(
"_"
);
switch
(
data
[
index
+
1
])
{
case
0
:
sb
.
Append
(
"anonymous"
);
break
;
case
1
:
sb
.
Append
(
"rsa"
);
break
;
case
2
:
sb
.
Append
(
"dsa"
);
break
;
case
3
:
sb
.
Append
(
"ecdsa"
);
break
;
case
7
:
sb
.
Append
(
"ed25519"
);
break
;
case
8
:
sb
.
Append
(
"ed448"
);
break
;
default
:
sb
.
AppendFormat
(
"Unknown[0x{0:X2}]"
,
data
[
index
+
1
]);
break
;
}
sb
.
AppendFormat
(
", "
);
index
+=
2
;
}
if
(
sb
.
Length
>
1
)
sb
.
Length
-=
2
;
return
sb
.
ToString
();
}
private
static
string
GetApplicationLayerProtocolNegotiation
(
byte
[]
data
)
{
List
<
string
>
stringList
=
new
List
<
string
>();
int
index
=
2
;
while
(
index
<
data
.
Length
)
{
int
count
=
data
[
index
];
stringList
.
Add
(
Encoding
.
ASCII
.
GetString
(
data
,
index
+
1
,
count
));
index
+=
1
+
count
;
}
return
string
.
Join
(
", "
,
stringList
.
ToArray
());
}
private
static
string
GetExtensionName
(
int
value
)
{
//https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
switch
(
value
)
{
case
0
:
return
"server_name"
;
case
1
:
return
"max_fragment_length"
;
case
2
:
return
"client_certificate_url"
;
case
3
:
return
"trusted_ca_keys"
;
case
4
:
return
"truncated_hmac"
;
case
5
:
return
"status_request"
;
case
6
:
return
"user_mapping"
;
case
7
:
return
"client_authz"
;
case
8
:
return
"server_authz"
;
case
9
:
return
"cert_type"
;
case
10
:
return
"supported_groups"
;
// renamed from "elliptic_curves"
case
11
:
return
"ec_point_formats"
;
case
12
:
return
"srp"
;
case
13
:
return
"signature_algorithms"
;
case
14
:
return
"use_srtp"
;
case
15
:
return
"heartbeat"
;
case
16
:
return
"ALPN"
;
// application_layer_protocol_negotiation
case
17
:
return
"status_request_v2"
;
case
18
:
return
"signed_certificate_timestamp"
;
case
19
:
return
"client_certificate_type"
;
case
20
:
return
"server_certificate_type"
;
case
21
:
return
"padding"
;
case
22
:
return
"encrypt_then_mac"
;
case
23
:
return
"extended_master_secret"
;
case
24
:
return
"token_binding"
;
// TEMPORARY - registered 2016-02-04, extension registered 2017-01-12, expires 2018-02-04
case
25
:
return
"cached_info"
;
case
35
:
return
"SessionTicket TLS"
;
case
13172
:
return
"next_protocol_negotiation"
;
case
30031
:
case
30032
:
return
"channel_id"
;
// Google
case
35655
:
return
"draft-agl-tls-padding"
;
case
65281
:
return
"renegotiation_info"
;
default
:
return
"unknown"
;
}
}
private
static
string
ByteArrayToString
(
byte
[]
data
)
{
return
string
.
Join
(
" "
,
data
.
Select
(
x
=>
x
.
ToString
(
"X2"
)));
}
}
public
class
Extension
{
public
int
Value
{
get
;
set
;
}
public
string
Name
{
get
;
set
;
}
public
string
Data
{
get
;
set
;
}
public
Extension
(
int
value
,
string
name
,
string
data
)
{
Value
=
value
;
Name
=
name
;
Data
=
data
;
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment