Skip to content

Commit

Permalink
Merge pull request #27 from scheiblingco:restore-rsa-algo-choice
Browse files Browse the repository at this point in the history
Misc. bugfixes, docs (RSA Alg, cert fingerprint error, docs)
  • Loading branch information
scheibling authored May 30, 2023
2 parents d5e7747 + 50f13ce commit cd58114
Show file tree
Hide file tree
Showing 10 changed files with 269 additions and 100 deletions.
35 changes: 29 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@

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

# Notice
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.

Notice from OpenSSH:
```
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
```

[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.


# Features
### SSH Keys
- Supports RSA, DSA, ECDSA and ED25519 keys
- Supports RSA, DSA (Note: Deprecated), ECDSA and ED25519 keys
- Import existing keys from file, string, byte data or [pyca/cryptography](https://github.com/pyca/cryptography) class
- Generate new keys
- Get public key from private keys
Expand All @@ -22,11 +33,7 @@ Python package for managing OpenSSH keypairs and certificates ([protocol.CERTKEY
- Export certificates to file, string or bytes

# Roadmap
- [x] Rewrite certificate field functionality for simpler usage
- [ ] Re-add functionality for changing RSA hash method
- [ ] Add CLI functionality
- [ ] Convert to/from putty format (keys only)

See issues for planned features and fixes

# Installation

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

## Building the documentation
```bash
pdoc3 src/sshkey_tools/ -o docs --html
cp -rf docs/sshkey_tools/* docs/
rm -rf docs/sshkey_tools
```

## SSH Keypairs (generating, loading, exporting)
```python
# Import the certificate classes
Expand Down Expand Up @@ -124,6 +138,7 @@ b"\0xc\0a\........"
The loaded private key objects can be used to sign bytestrings, and the public keys can be used to verify signatures on those
```python
from sshkey_tools.keys import RsaPrivateKey, RsaPublicKey
from sshkey_tools.fields import RsaAlgs

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

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

# When using an RSA key for the signature, you can specify the hashing algorithm
# The default algorithm is SHA512
signature = privkey.sign(signable_data, RsaAlgs.SHA512)

# Verify the signature (Throws exception if invalid)
pubkey.verify(signable_data, signature)
```
Expand Down Expand Up @@ -308,6 +327,10 @@ certificate.sign()
```

## Changelog
### 0.9.1
- Updated documentation
- Fix for bug where exception would occur when trying to export a key without a comment set

### 0.9
- Adjustments to certificate field handling for easier usage/syntax autocompletion
- Updated testing
Expand Down
32 changes: 25 additions & 7 deletions docs/cert.html
Original file line number Diff line number Diff line change
Expand Up @@ -540,17 +540,21 @@ <h2 id="raises">Raises</h2>
bytes(self.header), bytes(self.fields), bytes(self.footer)
)

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

Args:
**kwargs: Arguments to pass to the signature signing method
ex. hash_alg for RSA signatures

Raises:
_EX.NotSignedException: The certificate could not be signed

Returns:
bool: Whether successful
&#34;&#34;&#34;
if self.can_sign():
self.footer.signature.sign(data=self.get_signable())
self.footer.signature.sign(data=self.get_signable(), **kwargs)

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

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

Args:
**kwargs: Arguments to pass to the signature signing method
ex. hash_alg for RSA signatures

Raises:
_EX.NotSignedException: The certificate could not be signed

Returns:
bool: Whether successful
&#34;&#34;&#34;
if self.can_sign():
self.footer.signature.sign(data=self.get_signable())
self.footer.signature.sign(data=self.get_signable(), **kwargs)

return True
raise _EX.NotSignedException(&#34;There was an error while signing the certificate&#34;)
Expand Down Expand Up @@ -2672,10 +2680,16 @@ <h2 id="returns">Returns</h2>
</details>
</dd>
<dt id="sshkey_tools.cert.SSHCertificate.sign"><code class="name flex">
<span>def <span class="ident">sign</span></span>(<span>self) ‑> bool</span>
<span>def <span class="ident">sign</span></span>(<span>self, **kwargs) ‑> bool</span>
</code></dt>
<dd>
<div class="desc"><p>Sign the certificate</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>**kwargs</code></strong></dt>
<dd>Arguments to pass to the signature signing method
ex. hash_alg for RSA signatures</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>_EX.NotSignedException</code></dt>
Expand All @@ -2690,17 +2704,21 @@ <h2 id="returns">Returns</h2>
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def sign(self) -&gt; bool:
<pre><code class="python">def sign(self, **kwargs) -&gt; bool:
&#34;&#34;&#34;Sign the certificate

Args:
**kwargs: Arguments to pass to the signature signing method
ex. hash_alg for RSA signatures

Raises:
_EX.NotSignedException: The certificate could not be signed

Returns:
bool: Whether successful
&#34;&#34;&#34;
if self.can_sign():
self.footer.signature.sign(data=self.get_signable())
self.footer.signature.sign(data=self.get_signable(), **kwargs)

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

0 comments on commit cd58114

Please sign in to comment.