Compare commits
6 Commits
decfba6bd8
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
932c9adc52
|
|||
|
d9e78012e8
|
|||
|
8b4b46f283
|
|||
|
b1c028a8d0
|
|||
| 60b4196747 | |||
| b70dc3e07d |
@@ -3,71 +3,83 @@ td.linenos .normal { color: inherit; background-color: transparent; padding-left
|
||||
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
|
||||
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||
.codehilite .hll { background-color: #ffffcc }
|
||||
.codehilite .c { color: #3D7B7B; font-style: italic } /* Comment */
|
||||
.codehilite .err { border: 1px solid #FF0000 } /* Error */
|
||||
.codehilite .k { color: #008000; font-weight: bold } /* Keyword */
|
||||
.codehilite .o { color: #666666 } /* Operator */
|
||||
.codehilite .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
|
||||
.codehilite .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
|
||||
.codehilite .cp { color: #9C6500 } /* Comment.Preproc */
|
||||
.codehilite .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
|
||||
.codehilite .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
|
||||
.codehilite .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
|
||||
.codehilite .gd { color: #A00000 } /* Generic.Deleted */
|
||||
.codehilite .ge { font-style: italic } /* Generic.Emph */
|
||||
.codehilite .gr { color: #E40000 } /* Generic.Error */
|
||||
.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.codehilite .gi { color: #008400 } /* Generic.Inserted */
|
||||
.codehilite .go { color: #717171 } /* Generic.Output */
|
||||
.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
.codehilite .gs { font-weight: bold } /* Generic.Strong */
|
||||
.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.codehilite .gt { color: #0044DD } /* Generic.Traceback */
|
||||
.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||
.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||
.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
||||
.codehilite .kp { color: #008000 } /* Keyword.Pseudo */
|
||||
.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||
.codehilite .kt { color: #B00040 } /* Keyword.Type */
|
||||
.codehilite .m { color: #666666 } /* Literal.Number */
|
||||
.codehilite .s { color: #BA2121 } /* Literal.String */
|
||||
.codehilite .na { color: #687822 } /* Name.Attribute */
|
||||
.codehilite .nb { color: #008000 } /* Name.Builtin */
|
||||
.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
.codehilite .no { color: #880000 } /* Name.Constant */
|
||||
.codehilite .nd { color: #AA22FF } /* Name.Decorator */
|
||||
.codehilite .ni { color: #717171; font-weight: bold } /* Name.Entity */
|
||||
.codehilite .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
|
||||
.codehilite .nf { color: #0000FF } /* Name.Function */
|
||||
.codehilite .nl { color: #767600 } /* Name.Label */
|
||||
.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||
.codehilite .nv { color: #19177C } /* Name.Variable */
|
||||
.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
.codehilite .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.codehilite .mb { color: #666666 } /* Literal.Number.Bin */
|
||||
.codehilite .mf { color: #666666 } /* Literal.Number.Float */
|
||||
.codehilite .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
.codehilite .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
.codehilite .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
.codehilite .sa { color: #BA2121 } /* Literal.String.Affix */
|
||||
.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||
.codehilite .sc { color: #BA2121 } /* Literal.String.Char */
|
||||
.codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */
|
||||
.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
||||
.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */
|
||||
.codehilite .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
|
||||
.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */
|
||||
.codehilite .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
|
||||
.codehilite .sx { color: #008000 } /* Literal.String.Other */
|
||||
.codehilite .sr { color: #A45A77 } /* Literal.String.Regex */
|
||||
.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */
|
||||
.codehilite .ss { color: #19177C } /* Literal.String.Symbol */
|
||||
.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */
|
||||
.codehilite .fm { color: #0000FF } /* Name.Function.Magic */
|
||||
.codehilite .vc { color: #19177C } /* Name.Variable.Class */
|
||||
.codehilite .vg { color: #19177C } /* Name.Variable.Global */
|
||||
.codehilite .vi { color: #19177C } /* Name.Variable.Instance */
|
||||
.codehilite .vm { color: #19177C } /* Name.Variable.Magic */
|
||||
.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */
|
||||
|
||||
/* From https://github.com/richleland/pygments-css/blob/master/native.css */
|
||||
.codehilite .hll { background-color: #404040 }
|
||||
.codehilite { background: #202020; color: #d0d0d0 }
|
||||
.codehilite .c { color: #999999; font-style: italic } /* Comment */
|
||||
.codehilite .err { color: #a61717; background-color: #e3d2d2 } /* Error */
|
||||
.codehilite .esc { color: #d0d0d0 } /* Escape */
|
||||
.codehilite .g { color: #d0d0d0 } /* Generic */
|
||||
.codehilite .k { color: #6ab825; font-weight: bold } /* Keyword */
|
||||
.codehilite .l { color: #d0d0d0 } /* Literal */
|
||||
.codehilite .n { color: #d0d0d0 } /* Name */
|
||||
.codehilite .o { color: #d0d0d0 } /* Operator */
|
||||
.codehilite .x { color: #d0d0d0 } /* Other */
|
||||
.codehilite .p { color: #d0d0d0 } /* Punctuation */
|
||||
.codehilite .ch { color: #999999; font-style: italic } /* Comment.Hashbang */
|
||||
.codehilite .cm { color: #999999; font-style: italic } /* Comment.Multiline */
|
||||
.codehilite .cp { color: #cd2828; font-weight: bold } /* Comment.Preproc */
|
||||
.codehilite .cpf { color: #999999; font-style: italic } /* Comment.PreprocFile */
|
||||
.codehilite .c1 { color: #999999; font-style: italic } /* Comment.Single */
|
||||
.codehilite .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */
|
||||
.codehilite .gd { color: #d22323 } /* Generic.Deleted */
|
||||
.codehilite .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
|
||||
.codehilite .gr { color: #d22323 } /* Generic.Error */
|
||||
.codehilite .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
|
||||
.codehilite .gi { color: #589819 } /* Generic.Inserted */
|
||||
.codehilite .go { color: #cccccc } /* Generic.Output */
|
||||
.codehilite .gp { color: #aaaaaa } /* Generic.Prompt */
|
||||
.codehilite .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */
|
||||
.codehilite .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
|
||||
.codehilite .gt { color: #d22323 } /* Generic.Traceback */
|
||||
.codehilite .kc { color: #6ab825; font-weight: bold } /* Keyword.Constant */
|
||||
.codehilite .kd { color: #6ab825; font-weight: bold } /* Keyword.Declaration */
|
||||
.codehilite .kn { color: #6ab825; font-weight: bold } /* Keyword.Namespace */
|
||||
.codehilite .kp { color: #6ab825 } /* Keyword.Pseudo */
|
||||
.codehilite .kr { color: #6ab825; font-weight: bold } /* Keyword.Reserved */
|
||||
.codehilite .kt { color: #6ab825; font-weight: bold } /* Keyword.Type */
|
||||
.codehilite .ld { color: #d0d0d0 } /* Literal.Date */
|
||||
.codehilite .m { color: #3677a9 } /* Literal.Number */
|
||||
.codehilite .s { color: #ed9d13 } /* Literal.String */
|
||||
.codehilite .na { color: #bbbbbb } /* Name.Attribute */
|
||||
.codehilite .nb { color: #24909d } /* Name.Builtin */
|
||||
.codehilite .nc { color: #447fcf; text-decoration: underline } /* Name.Class */
|
||||
.codehilite .no { color: #40ffff } /* Name.Constant */
|
||||
.codehilite .nd { color: #ffa500 } /* Name.Decorator */
|
||||
.codehilite .ni { color: #d0d0d0 } /* Name.Entity */
|
||||
.codehilite .ne { color: #bbbbbb } /* Name.Exception */
|
||||
.codehilite .nf { color: #447fcf } /* Name.Function */
|
||||
.codehilite .nl { color: #d0d0d0 } /* Name.Label */
|
||||
.codehilite .nn { color: #447fcf; text-decoration: underline } /* Name.Namespace */
|
||||
.codehilite .nx { color: #d0d0d0 } /* Name.Other */
|
||||
.codehilite .py { color: #d0d0d0 } /* Name.Property */
|
||||
.codehilite .nt { color: #6ab825; font-weight: bold } /* Name.Tag */
|
||||
.codehilite .nv { color: #40ffff } /* Name.Variable */
|
||||
.codehilite .ow { color: #6ab825; font-weight: bold } /* Operator.Word */
|
||||
.codehilite .w { color: #666666 } /* Text.Whitespace */
|
||||
.codehilite .mb { color: #3677a9 } /* Literal.Number.Bin */
|
||||
.codehilite .mf { color: #3677a9 } /* Literal.Number.Float */
|
||||
.codehilite .mh { color: #3677a9 } /* Literal.Number.Hex */
|
||||
.codehilite .mi { color: #3677a9 } /* Literal.Number.Integer */
|
||||
.codehilite .mo { color: #3677a9 } /* Literal.Number.Oct */
|
||||
.codehilite .sa { color: #ed9d13 } /* Literal.String.Affix */
|
||||
.codehilite .sb { color: #ed9d13 } /* Literal.String.Backtick */
|
||||
.codehilite .sc { color: #ed9d13 } /* Literal.String.Char */
|
||||
.codehilite .dl { color: #ed9d13 } /* Literal.String.Delimiter */
|
||||
.codehilite .sd { color: #ed9d13 } /* Literal.String.Doc */
|
||||
.codehilite .s2 { color: #ed9d13 } /* Literal.String.Double */
|
||||
.codehilite .se { color: #ed9d13 } /* Literal.String.Escape */
|
||||
.codehilite .sh { color: #ed9d13 } /* Literal.String.Heredoc */
|
||||
.codehilite .si { color: #ed9d13 } /* Literal.String.Interpol */
|
||||
.codehilite .sx { color: #ffa500 } /* Literal.String.Other */
|
||||
.codehilite .sr { color: #ed9d13 } /* Literal.String.Regex */
|
||||
.codehilite .s1 { color: #ed9d13 } /* Literal.String.Single */
|
||||
.codehilite .ss { color: #ed9d13 } /* Literal.String.Symbol */
|
||||
.codehilite .bp { color: #24909d } /* Name.Builtin.Pseudo */
|
||||
.codehilite .fm { color: #447fcf } /* Name.Function.Magic */
|
||||
.codehilite .vc { color: #40ffff } /* Name.Variable.Class */
|
||||
.codehilite .vg { color: #40ffff } /* Name.Variable.Global */
|
||||
.codehilite .vi { color: #40ffff } /* Name.Variable.Instance */
|
||||
.codehilite .vm { color: #40ffff } /* Name.Variable.Magic */
|
||||
.codehilite .il { color: #3677a9 } /* Literal.Number.Integer.Long */
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjaYYHHBhcGF0dXR1
|
||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaA5/4P/1SU69isY6/kRRc2VpZ9MYni
|
||||
/pCd1yNtoYYC3yuMij22k7nx1osoEGofjdNiSp15DOZI/RVhKdeppU2BxJ8LuejB
|
||||
wllqjhU5sS2fa9Me0P7Sv33o9jQAUmPKVY3KmdwkNj+/Vd1gmxAYEhoU/9KhzRcF
|
||||
fF1wVFTfFbtRmHan/3yQbW807W2TnkqOi1c6i6PSCgf20H5rHglOdYzKr1+suQ6T
|
||||
nx1+2hYlKzPkMyU9+R21PPdU7+3lUMxuvJ301xIOGD3ri45FHKgg5rpagdJctC1w
|
||||
sVccXQERn0yuU40YHyAmXFy6BOuJk+8Eh7bb/8X/ASpuIjZccyyGlja/h5w3gYYm
|
||||
rni4ApdH+VtNZtSwTb4plxaktgEXiOvIvF0u7z2Xs4J4XPorvjFwq5nZU2A6MeNd
|
||||
hDfdmAOOfjfafgigQRSRbx35YInw45USccE9kyib/YlBDf2snCYXgGqGiREBmehf
|
||||
7tGS10NWidomhn14otlXB/H4kQ8PwjrfpwmDCXPhtCZAQ8g+YF5ynvzjcalQCxEK
|
||||
D1+0ADpmX7Gbz0AXrRu2mSbYJyJD+11+35KOM6mV1BMU8f3VVRB3FIwb8/jcU4T9
|
||||
V+Jcnz2KSjxKS9UXVXeGkXcYPEx3zYXwHOwlzfsLmq7wsvjZKSqqOCSicERP5KA2
|
||||
yZI/9w2nH5fS9S5ZP4rw
|
||||
=4/jw
|
||||
-----END PGP SIGNATURE-----
|
||||
@@ -1,17 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmPQYqwYHHBhcGF0dXR1
|
||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaAo3cP/2tX/q14L8SJInyupwlHyFUN
|
||||
fiENN4uLFdr0Uab6VtFIWWGJhmNasKC4uGbEb2YkRuLirtQYjSimTZKk47qOQ9AB
|
||||
UBE+FC8ryY3bfg6q+rleJFr4ElkpL6XcmYU5pTCcejRH9IrR/wptSmm7fdjiA/eN
|
||||
udwh9hTUvahLwkYOjKFJICj57lSqxrHZFbcS4qJiNrpMfqAjHJxnPbhADySf/gpd
|
||||
SNtlcTa+YezvJBsz6GDdBiRMBowFDVfswSYfyrtM+7V2CHOG4K0atVtg/2XlnegN
|
||||
L1Pu+vd+fXR7u03k08/3ru9qq6FhDFw+Kz9Obq3OlladkU5dCWvhTo0q/BJZQCDh
|
||||
xcWYua1bGJcziwcJwVHj9d8bfIqVBKF4xX+REG29I7OzxDaiVwUIWxPbz3X/R+d8
|
||||
ovmpMtLGA9HBvdiCj6dmnZgFWnTk/qacFbYNm2CN9XBBHy4SSwx7/hVyuU1i8RSh
|
||||
6Md7grZPlku3C3QrtuVDRZmWqxbKqdFcrD38SrV5n7ZyD2Az0hQVUFr9UEPp4smm
|
||||
2YbtL/iFpaJiMNL9nWTAx/B7td+3IuntYP81KLmPChhRguiE1mtufLh1j37Ibs6k
|
||||
YopFRISU/FSXZQg8STmDSxcussJYtThfoTCCmwk1JC/ABqxV4zlClmpkQa6r9Ua6
|
||||
q55Bvt0JMv+dfao4cydb
|
||||
=PTZb
|
||||
-----END PGP SIGNATURE-----
|
||||
@@ -1,17 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaAGeIP/0hNo1wq7xXKWYhQUVqk5mNq
|
||||
2sPPfxg3+6KNuidUmxnwIpXsIPEw7jJ3xh74hb6afWHH0ZitrIUoLszkcOkEJaNe
|
||||
Zz+5UfsQybdYbWUsmpJCNK9QKEvwOa7B1TLUeI1ZR6B9KVVIUApg8AEYzBGce5ON
|
||||
MroYc/oQgEZCm5cSmuVc/+yds/gFwvJUmEZOFbXyhl1jGr499fG5Q/khZ0bwPZP5
|
||||
swbUBij0A8nBHiso5k+pDPEUIS6mE6hKZBH+gr9/CefCj1LCyiKRDjeNujZqmiRH
|
||||
r2w/3nARAfr0Vd7X7P/Zsz3iKfP4/SEbHqY6mSGTWyahWajuiJWDMnM6HhIFHXbE
|
||||
RdH1HSDB2bj93TGHaNDwG/4l0FHyqGHmhtVMo243fXJv1zaLlSabTcXFa0wPEToA
|
||||
Z4OQcZWjDzumz2OnbBInaev8Q3aQsvkQERs3jbAw9HaKJqn/tOhPCFqrZRlvyhmV
|
||||
IvcWoPYtqaRA0MCjK7eDlMN1vcllR8owNXLN/xTKoNDPDAKOezalF2NgwNrBDqIM
|
||||
WEQBHRRa3Atm4aAOH8h8SZ+zYO63cmndCdpRA6eSmZ1lOO5NhmN9OfUX/ulLKFP9
|
||||
YEefJ0bfANnz2tjaogWAwQeZYSH5Pj51VvmQnwX5D1taBQXqMJbyMFfdsU45JQNu
|
||||
GYM5qpVHR7NDrj5X4uAG
|
||||
=t56n
|
||||
-----END PGP SIGNATURE-----
|
||||
@@ -1,17 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaA91MP+wX5e2v6CuaOEewjOFwhPWa1
|
||||
Naq31RhJvuYD3/leIVy4fZa+EkBgk9QNgnavOeKkM1bHlc6bZggE/sLwnTuhoXFX
|
||||
xSHil8oaF/7rNdgjjNUq8+N3Zo7GSGWJzOyZua/B91mubEDbwF9soqo2mXFzZBC3
|
||||
ZJODsWcK+l3lz9oiNGGxfa3NbkoNRF2falEYckeUoGg84xYknoSx8aGo8cbmyiRO
|
||||
aorTF7NtQMyhMXC4CfSoy/wjit1x+JYa11lr7epF4oy7yx+n0e5b58COkA5AEiL9
|
||||
XGzKe5IfphENj6tL6fnoiO80rXRQ34FaIjSLr/8kwKz/AQ5UIGeRybGPUdTaOz5D
|
||||
u9AVGD5HvLeUdwVilCf5Lhmutu9+0y86HImPoGYS6n7jZApIDelayaRHhmrcYT29
|
||||
yxCxHg9ulKBjq6Owbdqhfyf9oWB2gnHYnM8iD7bvJGkHJlLvIDaSsNyiOJeLs50S
|
||||
hU/UGuAnKRAqHRhZuYhW7Z8NVwxXeJ21lwCF3scxfSn65oAJKwSjIWIXnoEhzRaA
|
||||
hkLiL4Gq22simb/coNn94VC7xvY439Rvaes86ZYaLsyi5lMJUGtOFrmL33v0iCDB
|
||||
FS2l42UtMJxQsRezd8gd7IVRJrJynwymHwpu/8YuNP3n1kzv9cva/B7fsccBS5li
|
||||
1/lQA/A75nkqAqKyO/16
|
||||
=iSmJ
|
||||
-----END PGP SIGNATURE-----
|
||||
@@ -1,17 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaACLAP/2b44Gl5t6beFRRTDuwEWTtY
|
||||
q+88M9VFYJqoU9Fmvjeeiz5cdBi4PJRVK+U3He+Mxp8EcL64u3XUsKY6OnVJQ2t5
|
||||
dm1/uWEI8TUIYHGOKyqZtn0TrWUF6NoFsE/KmSWCq307dD0RRtLzDm6ztkE1XoPJ
|
||||
U/NP54ScCHA9StZPMA6UkLqv6pfV42eiCz3c42m4OfhAq4Ch1q5Nyuyh+GokQVA0
|
||||
wFtTLzXbJxJZgRvxLhT2tyBMWn2+kp6TfR6ZGkbzzdSObM7v1Cj5ZY0IVAt5wVQC
|
||||
JEXY5GZ/nyw5zzLyqkZjoDvzlhDCOKz4866uZr87rMAeFpmFb7YKed7sWD/72a8b
|
||||
z2dg+i8HOM7fm2FFffyPVROZ8WS1v3sZBayFQsNCMZ5hCKJfzqsIIUCYwZ6frNJ/
|
||||
BMv4bB5tSjmcEMD+pCQNTnRdqLdlZfRRAVIpwyPGPlzS9y+v6wNniyupM0AkeQii
|
||||
xS5rSXWEBok7Z8hOSX0J206aDDdXVkHhnR80JU3DC3SfDBohAMSfG/9bwnlYBZcS
|
||||
o3/P3q0u1alfKOgCJorb4sq3t2OdHsTrS3MYWgiyLNFKKfQktenAkToSecP0zgXe
|
||||
qVbrCuQmZnFuDjtPh45kEK61i/5YveLfHaZX2unHsja4V/vXPOsinvJVMnBsfEzp
|
||||
1SnNcGw4v1jzT/7Gx8Z3
|
||||
=eW+1
|
||||
-----END PGP SIGNATURE-----
|
||||
@@ -1,17 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaAymcQAKoksLNNyoEuE4/wzaNv56UA
|
||||
yqg+ylYz0vHnDYPgvawLolkQfrgbKzGa0zN3ugMvHR7sVQxdsT4BqmjSSs0CR1P9
|
||||
aWIfBBoPAB0OzKh7M64/K2vVeok/tbfa2Y5DFYGZbBuKDxJwr40Tfu4kJNk89LZQ
|
||||
KGed9+ZJo8STtdy7VjNL5sQIBMtGfFtNW9cYVR5Fr4uF/m2FKc6zYLXA5t3tbIWD
|
||||
RzIjD1s6GYLeLmj0ZGtgopLWX6ERIAtiveCn+LmPYtU+wsPBOv8Xg8+nQWq6bwpO
|
||||
8WHuQD049MZ/XRmeNnlBcfg7b1TIsZD5fya+rD85sKEXFWs4QMraDeAII+aJoZpd
|
||||
QyDafn7gj37E6ej+Q5qCuh7hsWslC4YaQek0GRlCygz/+Jn+NtnwXaNVEJs22j7V
|
||||
Lj6+2cUExQAX7MySNDdbwyS/PUrYrVLLagx6NW2OdII3UBz+A4srFb9RQ6dttWOE
|
||||
CzTHVY7BX4QalJyjc7Yex5do8lH/PZ23IsCSFE/r0I0kJes2Raq9eTyAISpvQSeZ
|
||||
HfvkiyrW3feOVfSjp64L7Y+lxmtgfo6HJhUZcb21OwlpLYJxRin+QOWHWbeg+fx0
|
||||
0EpJoKETofj8g5ErdZajFezr6odM27M3XGrTJIJJO6OqLv7fUYWc2Xmuf9+DXGTR
|
||||
fjVwJtmEIo/jR92saXgg
|
||||
=OXjT
|
||||
-----END PGP SIGNATURE-----
|
||||
@@ -1,17 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaAFAEP/0MMomPeqy56TnDjvG+fFEPC
|
||||
PPDexOXD8h0KVBGUdFGS7FPBn/O4ByKVE6Ki/y/2YttBt+P3RceT1eNjY+rPxFu9
|
||||
B7hcjli72G6dZ4bzofbNl3huG4oWmDEpX9CT87lL8vGU/4CqaKIk/dfBxuFPwqus
|
||||
5CyMX/ECMTjRNbQ75EKGE4vINht45pWFLzZUp+DKw4K2idOaQ8T+8vAKF0o10/Qr
|
||||
npDCAy0hIY9HWmYEI7JheUfMrw5jxYJ6vXIGHmsiVqX8DXxGpXXqevDhkFa6QEbA
|
||||
sgENJr5EvCR2ZeM3e566qYXSibCSfq58aXEVkt9yXrNrj0Q7Iz/uD7J5lR64e+rD
|
||||
Hv43p/lKbFRi7UAYpWR8nUXSX8wbzTETgT/WUeExD0AWIsyYAj33R7U1UngCL9qI
|
||||
IrkrPKnxBFRQTxl6v+MxEN7xAtKf9BWtbm+VQv+xuPtIE1dUof6oUKGA+f9qFrnR
|
||||
XucIZrGNbOfwfJ3P4w+crvI2WgqvH7vQSJbQPKNEXvQP9rYh5L7nG1IXqaHRQnuO
|
||||
kn9EcG/uQOkZUeo+8uvBJvSmcE9DiyYFfWvoDvpqtMfdolD+n8HXNfGFaGkHZ7+b
|
||||
RgFWmIGshVZo968y6iP9zyubdViF5JWl8r4pR6Y9MIbjiXOfgTPMpYpFL7lJQ2kr
|
||||
S1EEc4E/Axw0VYSk2jTw
|
||||
=WyMf
|
||||
-----END PGP SIGNATURE-----
|
||||
@@ -1,17 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaAE28P/0MZqiLeSDVP+W8eKaXrWh5i
|
||||
BfKDbRefdtV8/Ybs0MSCU9FyRv/PAvN7uA6KsBwptyJD8YMcJt1f8npjjN/E4In6
|
||||
uHz3EjjQmM5h4GIvnchN6IKL0CzkZspLH7thd5HXDYey7iEnu/b2P3W8MGdJbBYx
|
||||
x9dnGTDLm0y+x5FV8Lpe/UCgL1xTli0lpmUMKqzg58WFtrU2YD0y6jircxOKxyeO
|
||||
Rp0Sb2G/vfZL9oKVdK28zZ6CINCmNbYTaI/tqwTxoM9tB/+He+H4RaiAfFzU2/Ri
|
||||
jOm48xwr2Vmx2jvBk6mvQppIRtmy5tUOB9pFSTjQBCHL3hBUbN/nImAhpDl5u7CQ
|
||||
Y1xK60i42YFyiOj6vD551XoQNmgiJ7zVuJ3wy+k03wl1RujbRxnPkm2vwhPVPBBL
|
||||
1IWxoUPyTwpD6f/td2sZdqYGa8H+lRx8hjzwAw55zCF6KdCvLSWz6DBZUrQo1Wji
|
||||
nwVHcOtidfo3l9fH3xR8tshM2Rsv6XuKtyp3WkLJajW0r2et/bAyz29oU0BtGUlE
|
||||
dmjhCllGgtfJWz8r/XGiHgNQqiuJT3fMoQ2kVDrDMU1W4ffxleJGQbYDfhPOq1Pa
|
||||
JGE/JhaDAxhRXUlPdmVkkzuYE6WVwJu6FvaBzi9DJ2CkUl1UYk6jXl8n0pFrplXc
|
||||
AG9V+U0UmrLXc5ILN0Y6
|
||||
=bWDk
|
||||
-----END PGP SIGNATURE-----
|
||||
@@ -1,90 +0,0 @@
|
||||
-----BEGIN PGP MESSAGE-----
|
||||
|
||||
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
|
||||
H2bMsbwali44xssO0iWPmhdhekYg9aBVTl0sFw8x8CtkC8pxPXHD74ty1pnWJWra
|
||||
LFWrFsYv2v72HYV0Nv2i81UCU7lXTTaTDfrn9S4RT6rfoiEnvD5YMfmiUq35LJqS
|
||||
W9TyHZKNA9D80ABuTaVLVRNH1LJsemloksAg6GCBImlGEi1VfIKBi0WfmvbIpgVq
|
||||
YYfHIpsLhh39+S2OTOODS7YuXbT4uEUjp5659PunrP/VLy409h98/7IlyZflZUvw
|
||||
s/GrTguAbiKgmzbQzXlZZlxkLD8pWbpp+KRFN/V+uvLeFZWr1n9/8v4PjZ94fbv4
|
||||
0YnK/W/ufc1zf/GW3HHmimXs/OvdO676zqf3P/rAfvvua/be1PuxI49NHvVae7xH
|
||||
nv3w7Uuvmrrs7nO8zXde/cTDB/f9ZOmPq6f+48KfH/7Ifc9Et19/3tlX9jbLn9m5
|
||||
67rByZsX/35F+ex/lqOdj/i3HPPQkieqPznmDU9969rOvTc8N3b+L9k4O+Fb+647
|
||||
+e/71nzqLVfeevwn9tsHfnzePQ/ecHTsTRddvfcLV7xmYsMLbXHo5511fzrr619b
|
||||
9f7H9x7/9Cs/f/jMH9z21UO/vP69teW33bH5td/b9Id7//zuLdfO7jr+nIvv+trK
|
||||
G+u/vv+dG75+8w8fe/iaVxz+7NHBu55+nr/8tPVi95Mv+cynfnX6e06vvOyylzy7
|
||||
60sr9t+7d+WOY29o9R677+OltV9ed/Czj1829Y6By9eecfDWu/Y99b4jJ3zjA2/c
|
||||
uv6e1t9etWTzw1ecdlvpzfXBPau3P/W2z22//IV3/fSSq4+cSx7aeu2Pnmr8effn
|
||||
Zq57tG//Q1/+ypKBf23b4i37yJ8+f9/DD377vH0vfehHu/751xPffeTAih0HLn/m
|
||||
wHffeMuhxss/dnCbsfiJ3z535NEdz//1L8OHvmge/dknP/Cz+nHffPr5V5/x65kH
|
||||
1t/Y9+r4pOk9X3jhuHte5x5bOXbp1I4nLzUvdK45cMWKvU8SY8+XXvqvt009c2K8
|
||||
4a2Ha6dddCU/dfzQPTvO/c2zXxmeaN558i333bis9/G7Xz975HBr0cab/ni0/cjz
|
||||
P208uOWxmfX/Bg==
|
||||
=/2ew
|
||||
-----END PGP MESSAGE-----
|
||||
102
content/blog/2023-07-24-Android-Yubikey-Signing.md
Normal file
102
content/blog/2023-07-24-Android-Yubikey-Signing.md
Normal file
@@ -0,0 +1,102 @@
|
||||
<!-- title: Signing Android Apps Using a YubiKey (on NixOS) -->
|
||||
<!-- render: yes -->
|
||||
In my spare time, I currently develop two Android apps using *Flutter*: [AniTrack](https://codeberg.org/PapaTutuWawa/anitrack), a
|
||||
simple anime and manga tracker based on my own needs, and [Moxxy](https://moxxy.org), a modern XMPP
|
||||
client. While I don't provide release builds for AniTrack, I do for Moxxy. Those
|
||||
are signed using the key-pair that Flutter generates. I thought to myself: "Wouldn't it be cool if I could keep
|
||||
the key-pair on a separate device which does the signing for me?". The consequence
|
||||
of this thought is that I bought a *YubiKey 5c*. However, as always, using it for my
|
||||
purposes did not go without issues.
|
||||
|
||||
The first issue is that the official [*Android* documentation](https://developer.android.com/build/building-cmdline#deploy_from_bundle)
|
||||
says to use the `apksigner` tool for creating the signature. [The *YubiKey* documentation](https://developers.yubico.com/PIV/Guides/Android_code_signing.html), however,
|
||||
uses `jarsigner`. While I, at first, did not think much of it, *Android* has
|
||||
[different versions of the signature algorithm](https://source.android.com/docs/security/features/apksigning/): `v1` (what `jarsigner` does), `v2`, `v3`, `v3.1` and
|
||||
`v4`. While it seems like it would be no problem to just use `v1` signatures, *Flutter*, by default,
|
||||
generates `v1` and `v2` signatures, so I thought that I should keep it like that.
|
||||
|
||||
So, the solution is to just use `apksigner` instead of `jarsigner`, like [another person on the Internet](https://geoffreymetais.github.io/code/key-signing/) did.
|
||||
But that did not work for me. Running `apksigner` like that makes it complain that `apksigner` cannot
|
||||
access the required `sun.security.pkcs11.SunPKCS11` Java class.
|
||||
|
||||
```
|
||||
> /nix/store/ib27l0593bi4ybff06ndhpb8gyhx5zfv-android-sdk-env/share/android-sdk/build-tools/34.0.0/apksigner sign \
|
||||
--ks NONE \
|
||||
--ks-pass "pass:<YubiKey PIN>" \
|
||||
--provider-class sun.security.pkcs11.SunPKCS11 \
|
||||
--provider-arg ./provider.cfg \
|
||||
--ks-type PKCS11 \
|
||||
--min-sdk-version 24 \
|
||||
--max-sdk-version 34 \
|
||||
--in unsigned.apk \
|
||||
--out signed.apk
|
||||
|
||||
Exception in thread "main" java.lang.IllegalAccessException: class com.android.apksigner.ApkSignerTool$ProviderInstallSpec cannot access class sun.security.pkcs11.SunPKCS11 (in module jdk.crypto.cryptoki) because module jdk.crypto.cryptoki does not export sun.security.pkcs11 to unnamed module @75640fdb
|
||||
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)
|
||||
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)
|
||||
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:489)
|
||||
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
|
||||
at com.android.apksigner.ApkSignerTool$ProviderInstallSpec.installProvider(ApkSignerTool.java:1233)
|
||||
at com.android.apksigner.ApkSignerTool$ProviderInstallSpec.access$200(ApkSignerTool.java:1201)
|
||||
at com.android.apksigner.ApkSignerTool.sign(ApkSignerTool.java:343)
|
||||
at com.android.apksigner.ApkSignerTool.main(ApkSignerTool.java:92)
|
||||
```
|
||||
|
||||
It may only be an issue because I use NixOS, as I
|
||||
cannot find another instance of someone else having this issue. But I still want my APK signed using the key-pair
|
||||
on my *YubiKey*. After a lot of trial and error, I found out that I can force Java to export certain classes
|
||||
using the `--add-exports` flag. Since `apksigner` complained that the security classes are not exported to its
|
||||
unnamed class, I had to specify `--add-exports sun.security.pkcs11.SunPKCS11=ALL-UNNAMED`.
|
||||
|
||||
## My Setup
|
||||
|
||||
TL;DR: I wrapped this entire setup (minus the Gradle config as that's a per-project thing) into a fancy [script](https://codeberg.org/PapaTutuWawa/bits-and-bytes/src/branch/master/src/flutter/build.sh).
|
||||
|
||||
My provider configuration for the signature is exactly like the one provided in [previously mentioned blog post](https://geoffreymetais.github.io/code/key-signing/#set-up-your-own-management-key),
|
||||
with the difference that I cannot use the specified path to the `opensc-pkcs11.so` as I am on NixOS, where such
|
||||
paths are not used. So in my setup, I either use the Nix REPL to build the derivation for `opensc` and then
|
||||
use its `lib/opensc-pkcs11.so` path (`/nix/store/h2bn9iz4zqzmkmmjw9b43v30vhgillw4-opensc-0.22.0` in this case) for testing or, as
|
||||
used in [AniTrack](https://codeberg.org/PapaTutuWawa/anitrack/src/branch/master/flake.nix), let Nix figure out the path by building
|
||||
the config file from within my Nix Flake:
|
||||
|
||||
```nix
|
||||
{
|
||||
# ...
|
||||
providerArg = pkgs.writeText "provider-arg.cfg" ''
|
||||
name = OpenSC-PKCS11
|
||||
description = SunPKCS11 via OpenSC
|
||||
library = ${pkgs.opensc}/lib/opensc-pkcs11.so
|
||||
slotListIndex = 0
|
||||
'';
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
Next, to force Java to export the `sun.security.pkcs11.SunPKCS11` class to `apksigner`'s unnamed class, I added `--add-exports sun.security.pkcs11.SunPKCS11`
|
||||
to the Java command line. There are two ways of doing this:
|
||||
|
||||
1. Since `apksigner` is just a wrapper script around calling `apksigner.jar`, we could patch the wrapper script to include this parameter.
|
||||
2. Use the wrapper script's built-in mechanism to pass arguments to the `java` command.
|
||||
|
||||
While option 1 would work, it would require, in my case, to override the derivation that builds my Android SDK environment, which I am not that fond of.
|
||||
Using `apksigner`'s way of specifying Java arguments (`-J`) is much easier. However, there is a little trick to it: When you pass `-Jsomething` to `apksigner`,
|
||||
the wrapper scripts transforms it to `java -something`. As such, we cannot pass `-Jadd-exports sun.security.pkcs11.SunPKCS11` because it would get transformed
|
||||
to `java -add-exports sun.security.[...]`, which is not what we want. To work around this, I quote the entire parameter to trick Bash into thinking that I'm
|
||||
passing a single argument: `-J"-add-exports sun.security.pkcs11.SunPKCS11"`. This makes the wrapper append `--add-exports sun.security.pkcs11.SunPKCS11` to the
|
||||
Java command line, ultimately allowing me to sign unsigned Android APKs with the key-pair on my *YubiKey*.
|
||||
|
||||
Since signing a signed APK makes little sense, we also need to tell Gradle to *not* sign the APK. In the case of Flutter apps, I modified the `android/app/build.gradle`
|
||||
file to use a null signing config:
|
||||
|
||||
```gradle
|
||||
android {
|
||||
// ...
|
||||
buildTypes {
|
||||
release {
|
||||
// This prevents Gradle from signing release builds.
|
||||
// I don't care what happens to debug builds as I'm not distributing them.
|
||||
signingConfig null
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -7,6 +7,9 @@
|
||||
<link href="/assets/css/code.css" rel="stylesheet" />
|
||||
<link href="/feed.xml" type="application/atom+xml" rel="alternate" title="Moxxy Blog" />
|
||||
|
||||
<meta property="og:title" content="{{ title }}" />
|
||||
<meta property="og:description" content="{{ description }}" />
|
||||
|
||||
<!-- Blog -->
|
||||
<link rel="alternative"
|
||||
type="application/rss+xml"
|
||||
@@ -15,12 +18,14 @@
|
||||
|
||||
<!-- Optional MathJax -->
|
||||
{{ mathjax_include }}
|
||||
|
||||
<title>{{ title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex flex-col p-2 md:p-8 items-start md:w-4/5 mx-auto">
|
||||
<!-- Header -->
|
||||
<div class="flex flex-row self-center">
|
||||
<img class="w-12 h-12 md:w-24 md:h-24 rounded-lg" src="https://git.polynom.me/avatars/5b7b58054c0a93e5f66191f097d15215?size=870" alt="Profile picture"/>
|
||||
<img class="w-12 h-12 md:w-24 md:h-24 rounded-lg" src="{{ page_assets }}/img/avatar.jpg" alt="Profile picture"/>
|
||||
<div class="ml-4 self-center">
|
||||
<a class="self-center text-2xl font-bold" href="/">PapaTutuWawa's Blog</a>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user