Skip to content
This repository was archived by the owner on Jan 2, 2026. It is now read-only.

Commit 550d0a7

Browse files
committed
squashme: pushing my shit here also
1 parent 8b95b7d commit 550d0a7

File tree

3 files changed

+71
-5
lines changed

3 files changed

+71
-5
lines changed

migrations/0001_federated_identity.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ COMMENT ON TABLE public_keys IS 'Public keys of both actors, cached actors and h
2020
CREATE TABLE IF NOT EXISTS idcsr (
2121
id bigserial PRIMARY KEY,
2222
serial_number numeric(49, 0) UNIQUE NOT NULL,
23-
uaid uuid NOT NULL REFERENCES local_actors (uaid) ON DELETE CASCADE,
23+
uaid uuid NULL REFERENCES local_actors (uaid) ON DELETE CASCADE,
2424
subject_public_key_id bigint UNIQUE NOT NULL REFERENCES public_keys (id) ON DELETE CASCADE,
2525
subject_signature text UNIQUE NOT NULL,
2626
session_id varchar(32) NOT NULL,

src/database/idcert.rs

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
use std::fmt::Debug;
2+
13
use chrono::NaiveDateTime;
2-
use log::{debug, error};
4+
use log::{debug, error, warn};
35
use polyproto::{
46
certs::{PublicKeyInfo, idcert::IdCert},
57
der::Encode,
68
key::PublicKey,
79
signature::Signature,
810
types::DomainName,
911
};
10-
use sqlx::query;
12+
use sqlx::{query, types::Uuid};
1113

1214
use crate::{
1315
database::{AlgorithmIdentifier, Database, Issuer, SerialNumber},
@@ -109,9 +111,10 @@ impl HomeServerCert {
109111
/// * `Ok(())` if the certificate was successfully inserted
110112
/// * `Err(Error)` if the signature algorithm is unsupported or insertion
111113
/// fails
112-
pub(super) async fn insert_idcert_unchecked<S: Signature, P: PublicKey<S>>(
114+
pub(super) async fn insert_idcert_unchecked<S: Signature + Debug, P: PublicKey<S> + Debug>(
113115
db: &Database,
114116
cert: IdCert<S, P>,
117+
uaid: Option<&Uuid>,
115118
) -> Result<(), Error> {
116119
let oid_signature_algo = S::algorithm_identifier().oid;
117120
let params_signature_algo = match S::algorithm_identifier().parameters {
@@ -146,7 +149,57 @@ impl HomeServerCert {
146149
let issuer = Issuer::get_own(db).await?.expect(
147150
"The issuer entry for this sonata instance should have been added to the database on startup!",
148151
);
149-
let cert_serial = SerialNumber::from(cert.id_cert_tbs.serial_number);
152+
let subject_public_key_pem = cert.id_cert_tbs.subject_public_key.public_key_info().to_pem(polyproto::der::pem::LineEnding::LF).map_err(|e| {
153+
debug!("Received a public key which triggered an error when trying to convert it into PEM. Error: {e}; Public Key: {:?}", cert.id_cert_tbs.subject_public_key);
154+
Error::new(crate::errors::Errcode::IllegalInput, Some(Context::new(None, None, None, Some("Public Key could not be converted to PEM representation"))))
155+
})?;
156+
let subject_key_algorithm_identifier =
157+
match AlgorithmIdentifier::get_by_algorithm_identifier(
158+
db,
159+
&cert.id_cert_tbs.signature_algorithm,
160+
)
161+
.await?
162+
{
163+
Some(algo) => algo,
164+
None => {
165+
return Err(Error::new(
166+
crate::errors::Errcode::IllegalInput,
167+
Some(Context::new(
168+
None,
169+
None,
170+
None,
171+
Some(
172+
"ID-Cert contains cryptographic algorithms not supported by this server",
173+
),
174+
)),
175+
));
176+
}
177+
};
178+
let subject_public_keys = super::PublicKeyInfo::get_by(
179+
db,
180+
uaid.cloned(),
181+
Some(subject_public_key_pem),
182+
Some(subject_key_algorithm_identifier.id()),
183+
None,
184+
)
185+
.await?;
186+
let subject_public_key = match subject_public_keys.len() {
187+
0 => {
188+
return Err(Error::new(
189+
crate::errors::Errcode::IllegalInput,
190+
Some(Context::new_message("Your public key is not known by this server.")),
191+
));
192+
}
193+
1 => subject_public_keys[0],
194+
_ => {
195+
warn!(
196+
"Subject public key with PEM encoding {} has multiple matching entries in the database",
197+
subject_public_key_pem
198+
);
199+
return Err(Error::new_internal_error(None));
200+
}
201+
};
202+
let cert_serial = SerialNumber::from(cert.id_cert_tbs.serial_number.clone());
150203
if query!(
151204
"SELECT serial_number FROM idcsr WHERE serial_number = $1",
152205
cert_serial.as_bigdecimal()
@@ -164,6 +217,14 @@ impl HomeServerCert {
164217
cert_serial.as_bigdecimal()
165218
))));
166219
};
220+
let pem_encoded = cert.clone().to_pem(polyproto::der::pem::LineEnding::LF).map_err(|e| {
221+
debug!("Received a certificate which triggered an error when trying to convert it into PEM. Error: {e}; Certificate: {cert:?}");
222+
Error::new(crate::errors::Errcode::IllegalInput, Some(Context::new(None, None, None, Some("Certificate could not be converted to PEM representation"))))
223+
})?;
224+
cert.id_cert_tbs.subject; // TODO WE NEED THE SUBJECT;
225+
let record = query!("
226+
INSERT INTO idcsr (serial_number, uaid, subject_public_key_id, subject_signature, session_id, valid_not_before, valid_not_after, extensions, pem_encoded) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING idcsr
227+
", cert_serial, uaid, subject_public_key.id(), cert.signature.as_hex(), );
167228
// TODO: get pem_encoded string of cert and then I think we can actually insert
168229
// it into the DB!
169230
todo!()

src/errors.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,11 @@ impl Context {
244244
message: message.map(String::from).unwrap_or_default(),
245245
}
246246
}
247+
248+
/// Creates [Self], with only the `message` field being `Some`.
249+
pub fn new_message(message: &str) -> Self {
250+
Self::new(None, None, None, Some(message))
251+
}
247252
}
248253

249254
#[cfg(test)]

0 commit comments

Comments
 (0)