]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
third_party/heimdal: Import lorikeet-heimdal-202510122217 (commit c2d91bdde528ba018da...
authorJennifer Sutton <jennifersutton@catalyst.net.nz>
Sun, 12 Oct 2025 22:25:48 +0000 (11:25 +1300)
committerJennifer Sutton <jsutton@samba.org>
Wed, 22 Oct 2025 23:59:36 +0000 (23:59 +0000)
Signed-off-by: Jennifer Sutton <jennifersutton@catalyst.net.nz>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
18 files changed:
third_party/heimdal/.github/workflows/linux-mit-interop.yml
third_party/heimdal/.github/workflows/linux.yml
third_party/heimdal/.github/workflows/osx.yml
third_party/heimdal/.github/workflows/scanbuild.yml
third_party/heimdal/.github/workflows/ubsan.yml
third_party/heimdal/.github/workflows/valgrind.yml
third_party/heimdal/.github/workflows/windows.yml
third_party/heimdal/appl/test/Makefile.am
third_party/heimdal/cf/largefile.m4
third_party/heimdal/doc/copyright.texi
third_party/heimdal/kdc/pkinit.c
third_party/heimdal/lib/asn1/krb5.asn1
third_party/heimdal/lib/asn1/rfc2459.asn1
third_party/heimdal/lib/hdb/hdb.asn1
third_party/heimdal/lib/hdb/hdb.h
third_party/heimdal/lib/hx509/cert.c
third_party/heimdal/lib/hx509/cms.c
third_party/heimdal/lib/hx509/version-script.map

index d1837a01d8ca63879b64c5bb0261401c6bf6b612..36830e4114510c89d38f067e7c1b8193d8ed3945 100644 (file)
@@ -101,17 +101,17 @@ jobs:
                   git ls-files -o|grep -v ^build/
                 fi
             - name: Upload Install Tarball
-              uses: actions/upload-artifact@v2
+              uses: actions/upload-artifact@v4
               with:
                 name: Install Tarball
                 path: '~/heimdal-install-linux-${{ matrix.compiler }}.tgz'
             - name: Upload Dist Tarball
-              uses: actions/upload-artifact@v2
+              uses: actions/upload-artifact@v4
               with:
                 name: Dist Tarball
                 path: 'build/heimdal-*.tar.gz'
             - name: Upload Logs Tarball
-              uses: actions/upload-artifact@v2
+              uses: actions/upload-artifact@v4
               with:
                 name: Test Logs
                 path: '~/logs-linux-${{ matrix.compiler }}.tgz'
index 1bbfbb4ec246c874ea089e446f72f3f1c1e24231..983136b76b27debba641d4749cf041dabedb2ffe 100644 (file)
@@ -130,17 +130,17 @@ jobs:
                   git ls-files -o|grep -v ^build/
                 fi
             - name: Upload Install Tarball
-              uses: actions/upload-artifact@v2
+              uses: actions/upload-artifact@v4
               with:
                 name: Install Tarball
                 path: '~/heimdal-install-linux-${{ matrix.compiler }}.tgz'
             - name: Upload Dist Tarball
-              uses: actions/upload-artifact@v2
+              uses: actions/upload-artifact@v4
               with:
                 name: Dist Tarball
                 path: 'build/heimdal-*.tar.gz'
             - name: Upload Logs Tarball
-              uses: actions/upload-artifact@v2
+              uses: actions/upload-artifact@v4
               with:
                 name: Test Logs
                 path: '~/logs-linux-${{ matrix.compiler }}.tgz'
index 29aa05fc1f7c5b40ff717f42676519471584c504..fc6b4ad7b2bbaa7339014ef7e7acdd494feedec7 100644 (file)
@@ -113,12 +113,12 @@ jobs:
               run: |
                 find build -name \*.trs|xargs grep -lw FAIL|sed -e 's/trs$/log/'|xargs cat
             - name: Upload Install Tarball
-              uses: actions/upload-artifact@v2
+              uses: actions/upload-artifact@v4
               with:
                 name: Install Tarball
                 path: '~/heimdal-install-osx.tgz'
             - name: Upload Artifacts
-              uses: actions/upload-artifact@v2
+              uses: actions/upload-artifact@v4
               with:
                 name: Upload Test Logs
                 path: '~/logs-osx.cpio'
index 472b0b7e396a5f7f62540cc0b037fa4ae93fcac5..0b79c8b9ba6047973da80af747cecf3c8f9d71b6 100644 (file)
@@ -61,7 +61,7 @@ jobs:
               run: |
                 find build -name \*.trs|xargs grep -lw FAIL|sed -e 's/trs$/log/'|xargs cat
             - name: Upload Artifacts
-              uses: actions/upload-artifact@v2
+              uses: actions/upload-artifact@v4
               with:
                 name: Scan-Build Reports
                 path: '/tmp/scan-build*/'
index 9dec161d430c448f9a65da6f045552c6126303cc..515010ef01b1e0c9f79989b459201e30eeda6d12 100644 (file)
@@ -127,7 +127,7 @@ jobs:
               run: |
                 find build -name \*.trs | sed -e 's/trs$/log/' | xargs cat
             - name: Upload Logs Tarball
-              uses: actions/upload-artifact@v2
+              uses: actions/upload-artifact@v4
               with:
                 name: Test Logs
                 path: '~/logs-linux-${{ matrix.compiler }}.tgz'
index 8506df999ca2630a0fc675c198e594a65e8426db..f6079f6cf17463c0303fa6862d4b9fb609384a04 100644 (file)
@@ -65,7 +65,7 @@ jobs:
               run: |
                 find build -name \*.trs|xargs grep -lw FAIL | sed -e 's/trs$/log/' | xargs cat
             - name: Upload Artifacts
-              uses: actions/upload-artifact@v2
+              uses: actions/upload-artifact@v4
               with:
                 name: Test Logs
                 path: '~/logs-linux-valgrind.tgz'
index 0d3bad83b216209bfa1ccaad0e1184570d2b0f7b..a48545ac8763358b4f89029c1f6a3e73a707462d 100644 (file)
@@ -88,7 +88,7 @@ jobs:
                 nmake /f NTMakefile APPVEYOR=1 MAKEINFO=makeinfo NO_INSTALLERS=1
                 nmake /f NTMakefile APPVEYOR=1 MAKEINFO=makeinfo NO_INSTALLERS=1 test
             - name: Upload Artifacts
-              uses: actions/upload-artifact@v2
+              uses: actions/upload-artifact@v4
               with:
                 name: Objects
                 path: 'D:/a/heimdal/heimdal/out/'
index 7bc9b6f419df6f094caa9d91f3d8fa16a028c3c8..7b2f7b1903504c68caf64e2f5d0288214011b4ed 100644 (file)
@@ -4,6 +4,8 @@ include $(top_srcdir)/Makefile.am.common
 
 WFLAGS += $(WFLAGS_LITE)
 
+AUTOMAKE_OPTIONS = subdir-objects
+
 noinst_PROGRAMS = tcp_client tcp_server gssapi_server gssapi_client \
        uu_server uu_client nt_gss_server nt_gss_client http_client \
        kinit_auditdns
index cdbbc5543148553042e36271b6e008f3195fff58..6f20fc83c66a37ee621649211220897a202dcf3a 100644 (file)
@@ -7,10 +7,16 @@ AC_DEFUN([rk_SYS_LARGEFILE],[
 AC_REQUIRE([AC_SYS_LARGEFILE])dnl
 dnl need to set this on the command line, since it might otherwise break
 dnl with generated code, such as lex
-if test "$enable_largefile" != no -a "$ac_cv_sys_large_files" != no; then
-       CPPFLAGS="$CPPFLAGS -D_LARGE_FILES=$ac_cv_sys_large_files"
-fi
-if test "$enable_largefile" != no -a "$ac_cv_sys_file_offset_bits" != no && test -n "$ac_cv_sys_file_offset_bits"; then
-       CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits"
+if test "$enable_largefile" != no; then
+       if test -n "$ac_cv_sys_large_files" && test "$ac_cv_sys_large_files" != no; then
+               CPPFLAGS="$CPPFLAGS -D_LARGE_FILES=$ac_cv_sys_large_files"
+       fi
+       if test -n "$ac_cv_sys_file_offset_bits" && test "$ac_cv_sys_file_offset_bits" != no; then
+               CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits"
+       fi
+       if test -n "$ac_cv_sys_largefile_opts"; then
+               AS_CASE([$ac_cv_sys_largefile_opts],[-D_FILE_OFFSET_BITS=*|-D_LARGE_FILES=*],
+                       [CPPFLAGS="$CPPFLAGS $ac_cv_sys_largefile_opts"])
+       fi
 fi
 ])
index 886bf2cdaa05bb0b3e01b231a0a9444e3a237eca..7dd4cc9a0aec3ead3b294a2f6e70dd6fd2ba9296 100644 (file)
@@ -165,7 +165,32 @@ Tom's fast math (bignum support) and LibTomMath
 
 @verbatim
 
-LibTomMath is hereby released into the Public Domain.  
+                          The LibTom license
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/>
 
 @end verbatim 
 
index ea734dd50c732aab91c4742273fd9aac3accd4a3..fa39a42c35018d121cfdc3e689d7eba26e6435f7 100644 (file)
@@ -660,6 +660,31 @@ match_serial_number(
     return matched;
 }
 
+/**
+ * @brief Check to see if the certificate’s object SID matches the client’s.
+ *
+ * @param client[in]   client hdb record
+ * @param cert_sid[in] SID of certificate used to sign the request.
+ *
+ * @return TRUE the certificate matches
+ *         FALSE the certificate DOES NOT match
+ */
+static krb5_boolean
+match_object_sid(hdb_entry *client, ObjectSid *cert_sid)
+{
+    HDB_extension *ext = NULL;
+
+    ext = hdb_find_extension(client, choice_HDB_extension_data_object_sid);
+    if (ext == NULL) {
+       return FALSE;
+    }
+
+    /*
+     * Does the certificate’s object SID match the object SID for this client?
+     */
+    return der_heim_octet_string_cmp(&ext->data.u.object_sid, cert_sid) == 0;
+}
+
 /**
  * @brief Validate the certificate against the criteria outlined in KB5014754
  *
@@ -694,9 +719,9 @@ pk_check_certificate_binding(
     memset(&mappings, 0, sizeof(mappings));
 
     /*
-       * If there is no extension or the enforcement mode is none
-       * then there is nothing to do.
-       */
+     * If there is no extension or the enforcement mode is none, don’t
+     * perform any certificate mapping or object SID checks.
+     */
     ext = hdb_find_extension(client, choice_HDB_extension_data_cert_mappings);
     if (ext == NULL) {
        return 0;
@@ -707,73 +732,88 @@ pk_check_certificate_binding(
        goto out;
     }
 
-    /*
-     * If there are no mappings then reject the logon
-     */
-    if (mappings.mappings == NULL) {
-       ret = KRB5_KDC_ERR_CERTIFICATE_MISMATCH;
-       krb5_set_error_message(
-           context, ret, "Client has no certificate mappings");
-       goto out;
-    }
-
-    for (i = 0, matched = FALSE; i < mappings.mappings->len && !matched; i++) {
-       HDB_Ext_CertificateMapping *m = &mappings.mappings->val[i];
-
-       strong_mapping = m->strong_mapping;
-       /*
-        * When enforcement mode is full only consider strong mappings
-        */
-       if (mappings.enforcement_mode == hdb_enf_mode_full && !strong_mapping) {
-           continue;
-       }
+    if (mappings.mappings != NULL) {
+       for (i = 0, matched = FALSE; i < mappings.mappings->len && !matched; i++) {
+           HDB_Ext_CertificateMapping *m = &mappings.mappings->val[i];
 
-       if (m->issuer_name != NULL) {
-           hx509_name issuer;
-           ret = hx509_cert_get_issuer(*cert, &issuer);
-           if (ret != 0) {
+           strong_mapping = m->strong_mapping;
+           /*
+            *     When enforcement mode is full only consider strong mappings
+            */
+           if (mappings.enforcement_mode == hdb_enf_mode_full && !strong_mapping) {
                continue;
            }
-           matched = match_name(context, &issuer, m->issuer_name);
-           hx509_name_free(&issuer);
-           if (!matched) {
-               continue;
+
+           if (m->issuer_name != NULL) {
+               hx509_name issuer;
+               ret = hx509_cert_get_issuer(*cert, &issuer);
+               if (ret != 0) {
+                   ret = 0;
+                   continue;
+               }
+               matched = match_name(context, &issuer, m->issuer_name);
+               hx509_name_free(&issuer);
+               if (!matched) {
+                   krb5_warnx(context, "PKINIT: Issuer name does not match");
+                   continue;
+               }
            }
-       }
-       if (m->subject_name != NULL) {
-           hx509_name subject;
-           ret = hx509_cert_get_subject(*cert, &subject);
-           if (ret != 0) {
-               continue;
+           if (m->subject_name != NULL) {
+               hx509_name subject;
+               ret = hx509_cert_get_subject(*cert, &subject);
+               if (ret != 0) {
+                   ret = 0;
+                   continue;
+               }
+               matched = match_name(context, &subject, m->subject_name);
+               hx509_name_free(&subject);
+               if (!matched) {
+                   krb5_warnx(context, "PKINIT: Subject name does not match");
+                   continue;
+               }
            }
-           matched = match_name(context, &subject, m->subject_name);
-           hx509_name_free(&subject);
-           if (!matched) {
-               continue;
+           if (m->rfc822 != NULL) {
+               matched = match_rfc822_name(context, cert, m);
+               if (!matched) {
+                   krb5_warnx(context, "PKINIT: RFC822 name does not match");
+                   continue;
+               }
            }
-       }
-       if (m->rfc822 != NULL) {
-           matched = match_rfc822_name(context, cert, m);
-           if (!matched) {
-               continue;
+           if (m->ski != NULL) {
+               matched = match_subject_key_identifier(context, cert, m);
+               if (!matched) {
+                   krb5_warnx(context, "PKINIT: Subject key identifier does not match");
+                   continue;
+               }
            }
-       }
-       if (m->ski != NULL) {
-           matched = match_subject_key_identifier(context, cert, m);
-           if (!matched) {
-               continue;
+           if (m->public_key != NULL) {
+               matched = match_public_key(context, cert, m);
+               if (!matched) {
+                   continue;
+               }
            }
-       }
-       if (m->public_key != NULL) {
-           matched = match_public_key(context, cert, m);
-           if (!matched) {
-               continue;
+           if (m->serial_number != NULL) {
+               matched = match_serial_number(cert, m);
+               if (!matched) {
+                   krb5_warnx(context, "PKINIT: Serial number does not match");
+                   continue;
+               }
            }
        }
-       if (m->serial_number != NULL) {
-           matched = match_serial_number(cert, m);
+    }
+
+    if (!matched || !strong_mapping) {
+       ObjectSid cert_sid;
+
+       ret = hx509_cert_get_object_sid(*cert, &cert_sid);
+       if (ret) {
+           ret = 0;
+       } else {
+           strong_mapping = TRUE;
+           matched = match_object_sid(client, &cert_sid);
+           free_ObjectSid(&cert_sid);
            if (!matched) {
-               continue;
+               krb5_warnx(context, "PKINIT: Object SID does not match");
            }
        }
     }
index bf279a4b261c5bd3781ce440da2e050f0bd511b2..a9e58d54143c8bccc239ec2854ba0d87dbc968bb 100644 (file)
@@ -91,7 +91,8 @@ EXPORTS
        KERB-TGS-REQ-IN,
        KERB-TGS-REQ-OUT,
        KERB-ARMOR-SERVICE-REPLY,
-       KERB-ERROR-DATA
+       KERB-ERROR-DATA,
+       SidExtension
        ;
 
 NAME-TYPE ::= INTEGER {
index 7ceefe3309c0d543fd9c4c4034203ba741b6eda4..bc70d7e09b03c4a59ec39fcef5299284016597ce 100644 (file)
@@ -362,6 +362,8 @@ GeneralName ::= CHOICE {
 
 GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
 
+SidExtension ::= GeneralNames
+
 id-x509-ce-keyUsage OBJECT IDENTIFIER ::=  { id-x509-ce 15 }
 
 KeyUsage ::= BIT STRING {
@@ -508,6 +510,19 @@ id-x509-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::=  { id-x509-ce 54 }
 id-heim-ce-pkinit-princ-max-life OBJECT IDENTIFIER ::=
     { iso(1) member-body(2) se(752) su(43) heim-pkix(16) 4 }
 
+-- Microsoft extensions from MS-WCCE
+
+szOID-NTDS-CA-SECURITY-EXT OBJECT IDENTIFIER ::= {
+    iso(1) org(3) dod(6) internet(1) private(4) enterprise(1)
+    microsoft(311) directory-service(25) 2
+}
+
+szOID-NTDS-OBJECTSID OBJECT IDENTIFIER ::= {
+    iso(1) org(3) dod(6) internet(1) private(4) enterprise(1)
+    microsoft(311) directory-service(25) 2 1
+}
+
+ObjectSid ::= OCTET STRING
 
 DistributionPointReasonFlags ::= BIT STRING {
        unused                  (0),
@@ -920,6 +935,10 @@ on-pkinit-ms-san _OTHER-NAME ::= {
     &id id-pkix-on-pkinit-ms-san,
     &Type AliasUTF8String
 }
+on-ntds-objectsid _OTHER-NAME ::= {
+    &id szOID-NTDS-OBJECTSID,
+    &Type ObjectSid
+}
 
 KnownOtherNameTypes _OTHER-NAME ::= {
     on-xmppAddr
@@ -928,6 +947,7 @@ KnownOtherNameTypes _OTHER-NAME ::= {
   | on-permanentIdentifier
   | on-krb5PrincipalName
   | on-pkinit-ms-san
+  | on-ntds-objectsid
 }
 
 OtherName ::= OtherName{KnownOtherNameTypes}
index c890334df635df9254d239d0b8a2ab83a5d296ff..c3de24d7695183108cdfd39e11cdcf7a36ac42a4 100644 (file)
@@ -2,7 +2,8 @@
 HDB DEFINITIONS ::=
 BEGIN
 
-IMPORTS EncryptionKey, KerberosTime, Principal FROM krb5;
+IMPORTS EncryptionKey, KerberosTime, Principal FROM krb5
+       ObjectSid FROM rfc2459;
 
 hdb_db_format INTEGER ::= 2    -- format of database, 
                                -- update when making changes
@@ -244,6 +245,7 @@ HDB-extension ::= SEQUENCE {
                krb5-config[15]                 OCTET STRING,
                key-trust[16]                   HDB-Ext-KeyTrust,
                cert-mappings[17]               HDB-Ext-CertificateMappings,
+               object-sid[18]                  ObjectSid,
                ...
        },
        ...
index 8900df3e09ef3e3eeb98b02a1da17b758919aa50..576f0e46944b9fba930beb85c4ae25993dacb880 100644 (file)
@@ -65,7 +65,7 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
 #define HDB_F_GET_ANY          ( HDB_F_GET_CLIENT | \
                                  HDB_F_GET_SERVER | \
                                  HDB_F_GET_KRBTGT ) /* fetch any of client,server,krbtgt */
-#define HDB_F_CANON            0x00020 /* want canonicalition */
+#define HDB_F_CANON            0x00020 /* want canonicalization */
 #define HDB_F_ADMIN_DATA       0x00040 /* want data that kdc don't use  */
 #define HDB_F_KVNO_SPECIFIED   0x00080 /* we want a particular KVNO */
 #define HDB_F_LIVE_CLNT_KVNOS  0x00200 /* we want all live keys for pre-auth */
index 0034416e9feb43677e1acb1a150e989fadbf9e4f..d118b69a1b5b4e87a41f9c403e666693f08fdf1d 100644 (file)
 /**
  * @page page_cert The basic certificate
  *
- * The basic hx509 cerificate object in hx509 is hx509_cert. The
+ * The basic hx509 certificate object in hx509 is hx509_cert. The
  * hx509_cert object is representing one X509/PKIX certificate and
  * associated attributes; like private key, friendly name, etc.
  *
- * A hx509_cert object is usully found via the keyset interfaces (@ref
+ * A hx509_cert object is usually found via the keyset interfaces (@ref
  * page_keyset), but its also possible to create a certificate
  * directly from a parsed object with hx509_cert_init() and
  * hx509_cert_init_data().
@@ -623,7 +623,7 @@ hx509_verify_attach_anchors(hx509_verify_ctx ctx, hx509_certs set)
 }
 
 /**
- * Attach an revocation context to the verfication context, , makes an
+ * Attach an revocation context to the verification context, makes an
  * reference to the revoke context, so the consumer can free the
  * revoke context independent of the destruction of the verification
  * context. If there is no revoke context, the verification process is
@@ -649,7 +649,7 @@ hx509_verify_attach_revoke(hx509_verify_ctx ctx, hx509_revoke_ctx revoke_ctx)
  * set the current time will be used.
  *
  * @param ctx a verification context.
- * @param t the time the verifiation is using.
+ * @param t the time the verification is using.
  *
  *
  * @ingroup hx509_verify
@@ -673,7 +673,7 @@ _hx509_verify_get_time(hx509_verify_ctx ctx)
  * builder is going to try.
  *
  * @param ctx a verification context
- * @param max_depth maxium depth of the certificate chain, include
+ * @param max_depth maximum depth of the certificate chain, include
  * trust anchor.
  *
  * @ingroup hx509_verify
@@ -704,9 +704,9 @@ hx509_verify_set_proxy_certificate(hx509_verify_ctx ctx, int boolean)
 }
 
 /**
- * Select strict RFC3280 verification of certificiates. This means
+ * Select strict RFC3280 verification of certificates. This means
  * checking key usage on CA certificates, this will make version 1
- * certificiates unuseable.
+ * certificates unusable.
  *
  * @param ctx a verification context
  * @param boolean if non zero, use strict verification.
@@ -864,6 +864,34 @@ find_extension_eku(const Certificate *cert, ExtKeyUsage *eku)
                              eku, &size);
 }
 
+static int
+find_extension_ntds_security_extension(const Certificate *subject,
+                                      SidExtension *sid_extension)
+{
+    const Extension *e;
+    size_t size;
+    size_t i = 0;
+    int ret;
+
+    memset(sid_extension, 0, sizeof(*sid_extension));
+
+    e = find_extension(subject, &asn1_oid_szOID_NTDS_CA_SECURITY_EXT, &i);
+    if (e == NULL)
+       return HX509_EXTENSION_NOT_FOUND;
+
+    ret = decode_SidExtension(e->extnValue.data,
+                             e->extnValue.length,
+                             sid_extension,
+                             &size);
+    if (ret)
+       return ret;
+
+    if (size != e->extnValue.length)
+       return HX509_EXTRA_DATA_AFTER_STRUCTURE;
+
+    return ret;
+}
+
 static int
 add_to_list(hx509_octet_string_list *list, const heim_octet_string *entry)
 {
@@ -1676,7 +1704,7 @@ hx509_cert_get_subject(hx509_cert p, hx509_name *name)
 
 /**
  * Return the name of the base subject of the hx509 certificate. If
- * the certiicate is a verified proxy certificate, the this function
+ * the certificate is a verified proxy certificate, the this function
  * return the base certificate (root of the proxy chain). If the proxy
  * certificate is not verified with the base certificate
  * HX509_PROXY_CERTIFICATE_NOT_CANONICALIZED is returned.
@@ -1844,7 +1872,7 @@ hx509_cert_get_SPKI(hx509_context context, hx509_cert p, SubjectPublicKeyInfo *s
  * @param p a hx509 certificate object.
  * @param alg AlgorithmIdentifier, should be freed with
  *            free_AlgorithmIdentifier(). The algorithmidentifier is
- *            typicly rsaEncryption, or id-ecPublicKey, or some other
+ *            typically rsaEncryption, or id-ecPublicKey, or some other
  *            public key mechanism.
  *
  * @return An hx509 error code, see hx509_get_error_string().
@@ -1906,7 +1934,7 @@ hx509_cert_get_issuer_unique_id(hx509_context context, hx509_cert p, heim_bit_st
 }
 
 /**
- * Get a copy of the Subect Unique ID
+ * Get a copy of the Subject Unique ID
  *
  * @param context a hx509_context
  * @param p a hx509 certificate
@@ -1959,6 +1987,53 @@ hx509_cert_get_subject_key_identifier(hx509_context context,
     return ret;
 }
 
+/**
+ * Get a copy of the Object SID
+ *
+ * @param p a hx509 certificate
+ * @param sid the object SID returned, free with der_free_octet_string()
+ *
+ * @return An hx509 error code, see hx509_get_error_string(). The
+ * error code HX509_EXTENSION_NOT_FOUND is returned if the certificate
+ * doesn't have an object SID
+ *
+ * @ingroup hx509_cert
+ */
+
+HX509_LIB_FUNCTION int HX509_LIB_CALL
+hx509_cert_get_object_sid(hx509_cert p,
+                         ObjectSid *sid)
+{
+    SidExtension sid_ext;
+    int ret;
+
+    ret = find_extension_ntds_security_extension(p->data, &sid_ext);
+    if (ret) {
+       return ret;
+    }
+
+    if (sid_ext.len != 1) {
+       return HX509_CMS_INVALID_DATA;
+    }
+
+    if (sid_ext.val[0].element != choice_GeneralName_otherName) {
+       return HX509_CMS_INVALID_DATA;
+    }
+
+    if (sid_ext.val[0].u.otherName._ioschoice_value.element !=
+       choice_OtherName_iosnum_szOID_NTDS_OBJECTSID)
+    {
+       return HX509_CMS_INVALID_DATA;
+    }
+
+    if (!sid_ext.val[0].u.otherName._ioschoice_value.u.on_ntds_objectsid) {
+       return HX509_CMS_INVALID_DATA;
+    }
+
+    return der_copy_octet_string(
+       sid_ext.val[0].u.otherName._ioschoice_value.u.on_ntds_objectsid,
+       sid);
+}
 
 HX509_LIB_FUNCTION hx509_private_key HX509_LIB_CALL
 _hx509_cert_private_key(hx509_cert p)
index 1723f3a642405169b8bd8c8c31bcc5dd1bcddb22..a05dcf115d17b7ea37eaf4893f2679be16342fae 100644 (file)
@@ -1203,7 +1203,7 @@ add_one_attribute(Attribute **attr,
  * @param peer info about the peer the message to send the message to,
  * like what digest algorithm to use.
  * @param anchors trust anchors that the client will use, used to
- * polulate the certificates included in the message
+ * populate the certificates included in the message
  * @param pool certificates to use in try to build the path to the
  * trust anchors.
  * @param signed_data the output of the function, free with
index 9ba621d68a25603a47ef8ca4ac3e30d45d646fe3..6fd74b4a51f608fad3c1cb8421e71b7fde3ba93e 100644 (file)
@@ -105,6 +105,7 @@ HEIMDAL_X509_1.2 {
                hx509_cert_get_issuer;
                hx509_cert_get_notAfter;
                hx509_cert_get_notBefore;
+               hx509_cert_get_object_sid;
                hx509_cert_get_pkinit_max_life;
                hx509_cert_get_serialnumber;
                hx509_cert_get_subject;