Skip to content

Commit

Permalink
Fixes #157 we can now parse keyring files
Browse files Browse the repository at this point in the history
  • Loading branch information
kushaldas committed Jan 12, 2025
1 parent b2935bd commit 67cd866
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 0 deletions.
5 changes: 5 additions & 0 deletions docs/rustimplementation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ In most cases you don't have to use these, but if you have a reason, feel free t
.. versionchanged:: 0.16.0
`nullpolicy` argument was added.

.. function:: parse_keyring_file(certfile: str) -> List[...]:

This function can parse any given keyring file. It always uses `nullpolicy` and returns a list of Tuples (as mentioned above).

.. versionadded:: 0.16.0

.. function:: encrypt_bytes_to_file(publickeys, data, output, armor=False)

Expand Down
30 changes: 30 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2126,6 +2126,35 @@ fn parse_and_move_a_key(
//Ok(true)
}

/// Parses the given keyring file path, and returns list of tuples with various data.
///
/// - The first item of the tuple is a list of user ids as dictionary.
/// [{"value": xxx, "comment": "xxx", "email": "xxx", "uri": "xxx", "revoked": boolean}, ]
/// - Second item is the `fingerprint` as string.
/// - Boolean to mark if secret key or public
/// - expirationtime as datetime.datetime
/// - creationtime as datetime.datetime
/// - othervalues is another dictionary, inside of it.
/// - "subkeys": [("subkey keyid as hex", "fingerprint as hex", creationtime, expirationtime,
/// "keytype", "revoked as boolean")]. The subkey type can be of "encryption", "signing",
/// "authentication", or "unknown".
/// - "keyid": "primary key id in hex"
#[pyfunction]
fn parse_keyring_file(py: Python, certpath: String) -> Result<PyObject> {
let plist = PyList::empty_bound(py);
let ppr = PacketParser::from_file(certpath)?;
for certdata in CertParser::from(ppr) {
match certdata {
Ok(cert) => {
let data = internal_parse_cert(py, cert, true)?;
let _ = plist.append(data);
}
Err(err) => return Err(JceError::new(format!("{}", err))),
}
}
Ok(plist.into())
}

/// Parses the given file path, and returns a tuple with various data.
///
/// - The first item is a list of user ids as dictionary.
Expand Down Expand Up @@ -3298,6 +3327,7 @@ fn johnnycanencrypt(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(encrypt_filehandler_to_file))?;
m.add_wrapped(wrap_pyfunction!(parse_cert_file))?;
m.add_wrapped(wrap_pyfunction!(parse_cert_bytes))?;
m.add_wrapped(wrap_pyfunction!(parse_keyring_file))?;
m.add_wrapped(wrap_pyfunction!(encrypt_bytes_to_file))?;
m.add_wrapped(wrap_pyfunction!(encrypt_bytes_to_bytes))?;
m.add_wrapped(wrap_pyfunction!(encrypt_file_internal))?;
Expand Down
55 changes: 55 additions & 0 deletions tests/files/foo_keyring.asc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----

xjMEZ4LU/RYJKwYBBAHaRw8BAQdAwgF6ee4oYSe4n/uM2nCa1zuA4an3UwDsVncX
4tN3UpLCwBEEHxYKAIMFgmeC1P0FiQWfpgADCwkHCRBaDZG1obR5jkcUAAAAAAAe
ACBzYWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmfCp/xPH/WmmbrPXUj4muMc
uYcEZUFdJzqolOXK+pdJgwMVCggCmwECHgEWIQSVxUXjOKG8Q61g6AVaDZG1obR5
jgAAR5wBAMkew6qngGfVCKK+MPFbNLciIK4KgcyA9e8s7bR6Dx/6AQCSlmltTaFe
1BoCIGW+D5bwsKLktGRTV1r6yNj2srk9Cs0RYWxpY2VAZXhhbXBsZS5vcmfCwBQE
ExYKAIYFgmeC1P0FiQWfpgADCwkHCRBaDZG1obR5jkcUAAAAAAAeACBzYWx0QG5v
dGF0aW9ucy5zZXF1b2lhLXBncC5vcmcgB1GLKpaucIKs26WCjbluR/ALvJPip/lb
1HZo+oxZmwMVCggCmQECmwECHgEWIQSVxUXjOKG8Q61g6AVaDZG1obR5jgAA+6wA
/30FRHaBhD0i4KvC3v5KetZRvI55tY0Z0fuWxS3PmklgAP9+B+odSfPj5qhMN6jm
+fdZR4ShS3eo5v9kaYsUwl+zCM4zBGeC1P0WCSsGAQQB2kcPAQEHQJcJrj1VQ2+p
Yo/tHqNBfSrBZU7VIBsRGteCUbuX6OkOwsDFBBgWCgE3BYJngtT9BYkFn6YACRBa
DZG1obR5jkcUAAAAAAAeACBzYWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmcw
z1tm9XnUUbhzY6IOjBi7QvMbvzOS5lonNKycCK0gPwKbAr6gBBkWCgBvBYJngtT9
CRDGOKR6+z/0A0cUAAAAAAAeACBzYWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5v
cmd7m6dWe6dhKfSxuznPSy2PgQ1Y0rBXHGtmcyAMoBYErRYhBKCYnwkGMGqqEbkn
4sY4pHr7P/QDAACtbwD+PxJRqjQOQX0eHM3vs8ffSz61oOlBIrwyeIYTBUjiOUIA
/2wh8SkK5I4dewZyIGlJ7WDHOLXxIdFL8BFcNO1HDdMKFiEElcVF4zihvEOtYOgF
Wg2RtaG0eY4AAO10AQDCb0UALDF9jwuO+fbVrXqbNaTnvJYkoch98G7K63tRkgD9
Hk3oALzu0A9yc+Qrs+YXLhw1je1ocMb82htytAfAswnOOARngtT9EgorBgEEAZdV
AQUBAQdA/MRw88nUNer81sF3xE/xnJQLrYueH9QIA0z8jR5z/kEDAQgHwsAGBBgW
CgB4BYJngtT9BYkFn6YACRBaDZG1obR5jkcUAAAAAAAeACBzYWx0QG5vdGF0aW9u
cy5zZXF1b2lhLXBncC5vcmfLbHCaZkbJzp//yvFced4qxO8SPrFmAawHDJHGR6h+
QwKbDBYhBJXFReM4obxDrWDoBVoNkbWhtHmOAAAhqgD/R+tCDI4EAABY24tl6Gln
FwdEWhKcWNmG2UN5IY7rjgMA/RiILkQP8wzfIV2Y+9MyLE6cFmIR+o+lSOw3/iRI
fmcAxjMEZ4LU/RYJKwYBBAHaRw8BAQdAH8HLRMjzjinz9mBUvlyT/oldwIsq1rf3
EMLslyOstdDCwBEEHxYKAIMFgmeC1P0FiQWfpgADCwkHCRAfK0tu42vv1UcUAAAA
AAAeACBzYWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmfNs4iMicbZ8xxsuR+u
jYjK/CISJUbgrpI04tvgIvbTkgMVCggCmwECHgEWIQSEGPZIxH7tRopNq2gfK0tu
42vv1QAAuO8BAJwXqhJHyjcfPQP5mJx/jJ1EerZJQCpdeWyWY0BPhioOAP414wWe
oqlx4GzQsC5faHM32FsJjMumHaZIouqN+7rxAM0QbWFnbnVzQG1hZ251cy5zZcLA
FAQTFgoAhgWCZ4LU/QWJBZ+mAAMLCQcJEB8rS27ja+/VRxQAAAAAAB4AIHNhbHRA
bm90YXRpb25zLnNlcXVvaWEtcGdwLm9yZ/teSCNikY1vMiiCWlnA2lMCHy2oVCVA
tNfGnEv3JEFcAxUKCAKZAQKbAQIeARYhBIQY9kjEfu1Gik2raB8rS27ja+/VAAC9
gQEAlna2G41gZawiFi0fa9kv7IZNUAK99Hc5WBUEGAEzUq8BAItcoeyJQ9Gp8ryE
kXyifx9+MCCJY7OtmZxG1jiBIh0HzjMEZ4LU/RYJKwYBBAHaRw8BAQdAlKMzQOhR
oDkAatdSwGwndf1zyX/Q7ieenREBlRGgBAXCwMUEGBYKATcFgmeC1P0FiQWfpgAJ
EB8rS27ja+/VRxQAAAAAAB4AIHNhbHRAbm90YXRpb25zLnNlcXVvaWEtcGdwLm9y
Z2KccIg3fQG8fWzjBzoQKwdTvKoe0uIBqj2KfL4/zcyQApsCvqAEGRYKAG8FgmeC
1P0JEO5Fl3qiE4tkRxQAAAAAAB4AIHNhbHRAbm90YXRpb25zLnNlcXVvaWEtcGdw
Lm9yZwCJitFAUVEIZdvCoeyfTVR4AiIhrYSVvTNeNOHqM14bFiEEivqivuf6ZYFx
IOnj7kWXeqITi2QAAE6qAQDyuXunlULeM9+Tqy6VLGFjfGjUMglw2Q44bwCGhi7i
mAD/TrMHTFgKNelYs6bZioKSReO95u91GMHeLSGtDSwMjwYWIQSEGPZIxH7tRopN
q2gfK0tu42vv1QAAc94A/RBABU7I7p3nH/OjV6jsQ2g1chjZj1zHKM7bukXrxb6w
AP9Z3i0MQNQMoPvSiSkPcxv/UjVVBzfZfZ56AjK3UHgkDM44BGeC1P0SCisGAQQB
l1UBBQEBB0B0A2Qx/m8UJKO+PGkVxmFEcU6xocISdVeUGMqNwNRwCQMBCAfCwAYE
GBYKAHgFgmeC1P0FiQWfpgAJEB8rS27ja+/VRxQAAAAAAB4AIHNhbHRAbm90YXRp
b25zLnNlcXVvaWEtcGdwLm9yZ3NEqZT5HiXUkDVPnitBy6ytrjDUmYdMNbiwyovp
0W2QApsMFiEEhBj2SMR+7UaKTatoHytLbuNr79UAAMumAP0StizpmOX+R+ulxGof
4N2XGaaTUwFa9+aw+sRVf1NrYQEA9EuhA28Yfj4UUBDiJIIQxD59apWtDzk12OiV
IGwW6gE=
=ZhcD
-----END PGP PUBLIC KEY BLOCK-----
9 changes: 9 additions & 0 deletions tests/test_parse_cert.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@
from tests.conftest import BASE_TESTSDIR


def test_parse_keyring():
"""Tests parsing of a keyring file.
"""

ringpath = BASE_TESTSDIR / "files" / "foo_keyring.asc"
keys = rustjce.parse_keyring_file(str(ringpath))
assert len(keys) == 2


def test_parse_expired_old_cert():
"""Tests an old expried key.
Expand Down

0 comments on commit 67cd866

Please sign in to comment.