in cert/aziot-certd-config/src/lib.rs [228:274]
fn try_from(
subject: &CertSubject,
) -> Result<openssl::x509::X509Name, openssl::error::ErrorStack> {
// NOTE: X.509 requires CNs to be at most 64 characters.
//
// Ref: https://www.rfc-editor.org/rfc/rfc5280 PAGE 124
const CN_MAX_LENGTH: usize = 64;
#[inline]
fn truncate_cn_length(cn: &str) -> String {
// NOTE: An option that would allow returning a string reference is
// ```
// let mut it = cn.chars();
// let _ = it.by_ref().take(CN_MAX_LENGTH).last();
// &cn[..usize::try_from(unsafe { it.as_str().as_ptr().offset(cn.as_str().as_ptr()) }).unwrap()]
// ```
cn.chars().take(CN_MAX_LENGTH).collect()
}
let mut builder = openssl::x509::X509Name::builder()?;
match subject {
CertSubject::CommonName(cn) => {
builder
.append_entry_by_nid(openssl::nid::Nid::COMMONNAME, &truncate_cn_length(cn))?;
}
CertSubject::Subject(fields) => {
for (name, value) in fields {
// NOTE: Size limits exist for other X509Name fields as
// well [RFC5280]. We only truncate the Common Name since
// we have only encountered customer issues with Common Name
// length so far [1, 2].
//
// Ref[RFC5280]: https://www.rfc-editor.org/rfc/rfc5280
// Ref[1]: https://github.com/Azure/iotedge/issues/6288
// Ref[2]: https://github.com/Azure/iot-identity-service/pull/411#discussion_r871640144
if name.eq_ignore_ascii_case("cn") {
builder.append_entry_by_text(name, &truncate_cn_length(value))?;
} else {
builder.append_entry_by_text(name, value)?;
}
}
}
}
Ok(builder.build())
}