Skip to content

Commit

Permalink
Support certs with GeneralTime
Browse files Browse the repository at this point in the history
# Background

Recert until now only supported certs with asn1 `UTCTime` and not
`GeneralizedTime`.

# Problem

When golang creates certs with expiration way out in the future, it uses
`GeneralizedTime` instead of `UTCTime`.

For example:

```
    4:d=2  hl=2 l=  13 prim: UTCTIME           :240607174402Z
   19:d=2  hl=2 l=  17 prim: UTCTIME           :340605194402+0200
```

vs

```
    4:d=2  hl=2 l=  13 prim: UTCTIME           :240607174406Z
   19:d=2  hl=2 l=  19 prim: GENERALIZEDTIME   :21240514194406+0200
```

Usually this is not a problem, because a typical OCP cluster doesn't
have certs this far in the future, but eventually it will become a
problem. Also RHOAI has a component (tektoncd) that has certs with
expiry 100 years in the future [1] (despite the misleading name that
says "Decade" rather than "Century").

Trying to recert a cluster with tektoncd will therefore lead to the
following error:

```
error: |-
  scanning and recertification

  Caused by:
      0: processing discovered objects
      1: regenerating crypto
      2: re-signing cert with subject CN=tekton-triggers-core-interceptors.openshift-pipelines.svc, O=knative.dev
      3: mutating cert
      4: extending expiration
      5: forcefully expiring
      6: evaluating current expiration
      7: GeneralTime not supported
```

# Solution

This PR adds support for asn1 generalized time in recert. It's simply a
matter of casting the type correctly, the x509_certificate crate already
supports it.

# Testing

This PR is untested, waiting for feedback from the user that reported
the issue.

[1] https://github.com/tektoncd/triggers/blob/59da11dd50424c9ccef883b558671e34efc0eba5/pkg/interceptors/server/server.go#L36
  • Loading branch information
omertuc committed Oct 10, 2024
1 parent a142761 commit de2b5f7
Showing 1 changed file with 10 additions and 12 deletions.
22 changes: 10 additions & 12 deletions src/cluster_crypto/cert_key_pair/cert_mutations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use der::asn1::Ia5String;
use der::{Decode, Encode};
use x509_cert::ext::pkix::name::GeneralName::{DnsName, IpAddress};
use x509_cert::ext::pkix::SubjectAltName;
use x509_certificate::asn1time::UtcTime;
use x509_certificate::rfc3280::{AttributeTypeAndValue, Name};
use x509_certificate::{rfc3280, rfc4519::OID_COMMON_NAME, rfc5280::TbsCertificate};

Expand Down Expand Up @@ -66,19 +67,16 @@ fn extend_certificate_expiration(tbs_certificate: &mut TbsCertificate) -> Result
}

fn get_certificate_expiration(tbs_certificate: &mut TbsCertificate) -> Result<(DateTime<Utc>, DateTime<Utc>)> {
let (current_not_before, current_not_after) = match &tbs_certificate.validity.not_before {
x509_certificate::asn1time::Time::UtcTime(not_before) => {
match &tbs_certificate.validity.not_after {
x509_certificate::asn1time::Time::UtcTime(not_after) => {
// Dereferencing is the only way to get a chrono::DateTime out of the
// x509_certificate::asn1time::UtcTime struct.
(*(not_before.clone()), *(not_after.clone()))
}
x509_certificate::asn1time::Time::GeneralTime(_) => bail!("GeneralTime not supported"),
}
}
x509_certificate::asn1time::Time::GeneralTime(_) => bail!("GeneralTime not supported"),
let current_not_before: DateTime<Utc> = match &tbs_certificate.validity.not_before {
x509_certificate::asn1time::Time::UtcTime(not_before) => *(not_before.clone()),
x509_certificate::asn1time::Time::GeneralTime(not_before) => (*not_before).clone().into(),
};

let current_not_after: DateTime<Utc> = match &tbs_certificate.validity.not_after {
x509_certificate::asn1time::Time::UtcTime(not_after) => *(not_after.clone()),
x509_certificate::asn1time::Time::GeneralTime(not_after) => (*not_after).clone().into(),
};

Ok((current_not_before, current_not_after))
}

Expand Down

0 comments on commit de2b5f7

Please sign in to comment.