Skip to content

Commit cd58114

Browse files
authored
Merge pull request #27 from scheiblingco:restore-rsa-algo-choice
Misc. bugfixes, docs (RSA Alg, cert fingerprint error, docs)
2 parents d5e7747 + 50f13ce commit cd58114

File tree

10 files changed

+269
-100
lines changed

10 files changed

+269
-100
lines changed

README.md

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,20 @@
22

33
Python package for managing OpenSSH keypairs and certificates ([protocol.CERTKEYS](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.certkeys)). Supported functionality includes:
44

5+
# Notice
6+
The DSA algorithm is considered deprecated and will be removed in a future version. If possible, use RSA, [(ECDSA)](https://billatnapier.medium.com/ecdsa-weakness-where-nonces-are-reused-2be63856a01a) or ED25519 as a first-hand choice.
7+
8+
Notice from OpenSSH:
9+
```
10+
OpenSSH 7.0 and greater similarly disable the ssh-dss (DSA) public key algorithm. It too is weak and we recommend against its use. It can be re-enabled using the HostKeyAlgorithms configuration option: sshd_config(5) HostKeyAlgorithms
11+
```
12+
13+
[ECDSA has some flaws](https://billatnapier.medium.com/ecdsa-weakness-where-nonces-are-reused-2be63856a01a), especially when using short nonces or re-using nonces, it can still be used but exercise some caution in regards to nonces/re-signing identical data multiple times.
14+
15+
516
# Features
617
### SSH Keys
7-
- Supports RSA, DSA, ECDSA and ED25519 keys
18+
- Supports RSA, DSA (Note: Deprecated), ECDSA and ED25519 keys
819
- Import existing keys from file, string, byte data or [pyca/cryptography](https://github.com/pyca/cryptography) class
920
- Generate new keys
1021
- Get public key from private keys
@@ -22,11 +33,7 @@ Python package for managing OpenSSH keypairs and certificates ([protocol.CERTKEY
2233
- Export certificates to file, string or bytes
2334

2435
# Roadmap
25-
- [x] Rewrite certificate field functionality for simpler usage
26-
- [ ] Re-add functionality for changing RSA hash method
27-
- [ ] Add CLI functionality
28-
- [ ] Convert to/from putty format (keys only)
29-
36+
See issues for planned features and fixes
3037

3138
# Installation
3239

@@ -49,6 +56,13 @@ pip3 install ./
4956
# Documentation
5057
You can find the full documentation at [scheiblingco.github.io/sshkey-tools/](https://scheiblingco.github.io/sshkey-tools/)
5158

59+
## Building the documentation
60+
```bash
61+
pdoc3 src/sshkey_tools/ -o docs --html
62+
cp -rf docs/sshkey_tools/* docs/
63+
rm -rf docs/sshkey_tools
64+
```
65+
5266
## SSH Keypairs (generating, loading, exporting)
5367
```python
5468
# Import the certificate classes
@@ -124,6 +138,7 @@ b"\0xc\0a\........"
124138
The loaded private key objects can be used to sign bytestrings, and the public keys can be used to verify signatures on those
125139
```python
126140
from sshkey_tools.keys import RsaPrivateKey, RsaPublicKey
141+
from sshkey_tools.fields import RsaAlgs
127142

128143
signable_data = b'This is a message that will be signed'
129144

@@ -133,6 +148,10 @@ pubkey = RsaPrivateKey.public_key
133148
# Sign the data
134149
signature = privkey.sign(signable_data)
135150

151+
# When using an RSA key for the signature, you can specify the hashing algorithm
152+
# The default algorithm is SHA512
153+
signature = privkey.sign(signable_data, RsaAlgs.SHA512)
154+
136155
# Verify the signature (Throws exception if invalid)
137156
pubkey.verify(signable_data, signature)
138157
```
@@ -308,6 +327,10 @@ certificate.sign()
308327
```
309328

310329
## Changelog
330+
### 0.9.1
331+
- Updated documentation
332+
- Fix for bug where exception would occur when trying to export a key without a comment set
333+
311334
### 0.9
312335
- Adjustments to certificate field handling for easier usage/syntax autocompletion
313336
- Updated testing

docs/cert.html

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -540,17 +540,21 @@ <h2 id="raises">Raises</h2>
540540
bytes(self.header), bytes(self.fields), bytes(self.footer)
541541
)
542542

543-
def sign(self) -&gt; bool:
543+
def sign(self, **kwargs) -&gt; bool:
544544
&#34;&#34;&#34;Sign the certificate
545545

546+
Args:
547+
**kwargs: Arguments to pass to the signature signing method
548+
ex. hash_alg for RSA signatures
549+
546550
Raises:
547551
_EX.NotSignedException: The certificate could not be signed
548552

549553
Returns:
550554
bool: Whether successful
551555
&#34;&#34;&#34;
552556
if self.can_sign():
553-
self.footer.signature.sign(data=self.get_signable())
557+
self.footer.signature.sign(data=self.get_signable(), **kwargs)
554558

555559
return True
556560
raise _EX.NotSignedException(&#34;There was an error while signing the certificate&#34;)
@@ -2164,17 +2168,21 @@ <h3>Inherited members</h3>
21642168
bytes(self.header), bytes(self.fields), bytes(self.footer)
21652169
)
21662170

2167-
def sign(self) -&gt; bool:
2171+
def sign(self, **kwargs) -&gt; bool:
21682172
&#34;&#34;&#34;Sign the certificate
21692173

2174+
Args:
2175+
**kwargs: Arguments to pass to the signature signing method
2176+
ex. hash_alg for RSA signatures
2177+
21702178
Raises:
21712179
_EX.NotSignedException: The certificate could not be signed
21722180

21732181
Returns:
21742182
bool: Whether successful
21752183
&#34;&#34;&#34;
21762184
if self.can_sign():
2177-
self.footer.signature.sign(data=self.get_signable())
2185+
self.footer.signature.sign(data=self.get_signable(), **kwargs)
21782186

21792187
return True
21802188
raise _EX.NotSignedException(&#34;There was an error while signing the certificate&#34;)
@@ -2672,10 +2680,16 @@ <h2 id="returns">Returns</h2>
26722680
</details>
26732681
</dd>
26742682
<dt id="sshkey_tools.cert.SSHCertificate.sign"><code class="name flex">
2675-
<span>def <span class="ident">sign</span></span>(<span>self) ‑> bool</span>
2683+
<span>def <span class="ident">sign</span></span>(<span>self, **kwargs) ‑> bool</span>
26762684
</code></dt>
26772685
<dd>
26782686
<div class="desc"><p>Sign the certificate</p>
2687+
<h2 id="args">Args</h2>
2688+
<dl>
2689+
<dt><strong><code>**kwargs</code></strong></dt>
2690+
<dd>Arguments to pass to the signature signing method
2691+
ex. hash_alg for RSA signatures</dd>
2692+
</dl>
26792693
<h2 id="raises">Raises</h2>
26802694
<dl>
26812695
<dt><code>_EX.NotSignedException</code></dt>
@@ -2690,17 +2704,21 @@ <h2 id="returns">Returns</h2>
26902704
<summary>
26912705
<span>Expand source code</span>
26922706
</summary>
2693-
<pre><code class="python">def sign(self) -&gt; bool:
2707+
<pre><code class="python">def sign(self, **kwargs) -&gt; bool:
26942708
&#34;&#34;&#34;Sign the certificate
26952709

2710+
Args:
2711+
**kwargs: Arguments to pass to the signature signing method
2712+
ex. hash_alg for RSA signatures
2713+
26962714
Raises:
26972715
_EX.NotSignedException: The certificate could not be signed
26982716

26992717
Returns:
27002718
bool: Whether successful
27012719
&#34;&#34;&#34;
27022720
if self.can_sign():
2703-
self.footer.signature.sign(data=self.get_signable())
2721+
self.footer.signature.sign(data=self.get_signable(), **kwargs)
27042722

27052723
return True
27062724
raise _EX.NotSignedException(&#34;There was an error while signing the certificate&#34;)</code></pre>

0 commit comments

Comments
 (0)