RFC 10031

Media Access Control (MAC) Addresses in X.509 Certificates

πŸ“… published August 2026, from ietf

RFC 10031: Media Access Control (MAC) Addresses in X.509 Certificates πŸ’–

Okay bestie, let's get the title block sorted first πŸŽ€ This is RFC 10031 from the Internet Engineering Task Force (IETF). It's a Standards Track doc with ISSN 2070-1721, dated August 2026 ✨

The authors are R. Housley (Vigil Security), C. Bonnell (TurboLight Solutions), J. Mandel (AKAYLA), T. Okubo (Penguin Securities), and M. StJohns (NthPermutation Security LLC) 🫢 The header doesn't have an Obsoletes or Updates line, so it doesn't list anything it replaces or updates πŸ¦‹


Abstract ✨

This doc creates a brand-new GeneralName.otherName for the X.509 Subject Alternative Name (SAN) and Issuer Alternative Name (IAN) extensions, so they can carry an IEEE Media Access Control (MAC) address πŸ”₯ That means you can bind a Layer 2 interface identifier to a public key certificate, and it's giving main character energy. It also defines how constraints on this name form get encoded and processed in the X.509 Name Constraints extension (NCE) πŸ’…

Status of This Memo πŸ“œ

Okay, legal stuff, but make it cute πŸŽ€ This is an Internet Standards Track document. It comes from the IETF, represents the consensus of the IETF community, got public review, and was approved for publication by the Internet Engineering Steering Group (IESG). For more on Internet Standards, check Section 2 of RFC 7841 🌸

You can find the current status, any errata, and how to send feedback at https://www.rfc-editor.org/info/rfc10031 πŸ’œ

Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.

This doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License 🫢

Table of Contents πŸ“š

   1.  Introduction
   2.  Conventions and Definitions
   3.  MACAddress otherName
     3.1.  Encoding a MACAddress as an Alternative Name
     3.2.  Encoding a MACAddress Constraint
     3.3.  Generation and Validation Rules
     3.4.  Path Processing for the Name Constraints Extension
       3.4.1.  Matching Rules
       3.4.2.  OtherName.MACAddress Path Validation Processing
   4.  Security Considerations
     4.1.  Privacy Considerations
   5.  IANA Considerations
   6.  ASN.1 Module
   7.  MAC Address otherName Examples
     7.1.  EUI-48 Identifier
     7.2.  EUI-64 Identifier
     7.3.  EUI-48 Constraint for Universal, Unicast Addresses
   8.  References
     8.1.  Normative References
     8.2.  Informative References
   Acknowledgments
   Authors' Addresses

1. Introduction 🧚

Deployments that use X.509 certificates to identify a device by a Media Access Control (MAC) address need a standard way to encode it in the Subject Alternative Name (SAN) extension defined in [RFC5280] πŸ¦‹ This doc defines a new otherName form "MACAddress". The name form carries either a 48-bit IEEE 802 MAC address (EUI-48) or a 64-bit extended identifier (EUI-64) in an OCTET STRING [X680]. The name form can also convey constraints on EUI-48 or EUI-64 values when it's included in the Name Constraints extension (NCE) defined in Section 4.2.1.10 of [RFC5280] ✨ The new name form enables certificate-based authentication at Layer 2 and facilitates secure provisioning in Internet of Things (IoT) and automotive networks, in particular πŸš—

Heads up πŸ™ˆ While this construct may be used to carry EUI-48 or EUI-64 addresses in an Issuer Alternative Name (IAN) extension, there are probably few, if any, reasons to do so.

2. Conventions and Definitions πŸ“

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here 🫢

3. MACAddress otherName 🌸

In this doc, "otherName", "OtherName", and "GeneralName.otherName" all refer to a GeneralName.otherName field included in a SAN or IAN. The new name form is identified by the OBJECT IDENTIFIER (OID) id-on-MACAddress (1.3.6.1.5.5.7.8.12) and is declared below using the OTHER-NAME class declaration syntax 🧩 It has variants to convey an EUI-48 as an OCTET STRING consisting of 6 octets, or an EUI-64 as an OCTET STRING consisting of 8 octets. Constraints on EUI-48 and EUI-64 values are conveyed as OCTET STRINGs whose lengths are twice the octet length of the identifiers. The first set of N octets (where N is the length of the address octets) define the bit pattern of the constraint that the address must match, and the second set of N octets defines the bit mask that defines the set of significant bits in the bit pattern πŸ”₯

The subsections below explain how to encode EUI-48 and EUI-64 values and their matching constraints πŸ’–

3.1. Encoding a MACAddress as an Alternative Name πŸŽ€

When the name form is included in a SAN or IAN extension as an OtherName, the syntax consists of exactly six or eight octets. Values are encoded with the most significant octet encoded first ("big-endian" or "left-to-right" encoding) πŸ“ No text representation is permitted in the certificate, since human-readable forms such as 00-24-98-7B-19-02 or 0024.987B.1902 are used only in management interfaces. When a device possesses a 48-bit MAC identifier, the Certification Authority (CA) MUST encode it using a 6-octet OCTET STRING as the MACAddress value. When the device's factory identifier is a 64-bit EUI-64, or when no canonical 48-bit form exists, the CA MUST encode it using an 8-octet OCTET STRING as the MACAddress value πŸ’…

Example:

00-24-98-7B-19-02 encodes as OCTET STRING '0024987B1902'H.

3.2. Encoding a MACAddress Constraint 🧩

When the name form is included in the NCE, the syntax consists of an OCTET STRING that is twice as long as the OCTET STRING representation of the address type being constrained. Two elements get encoded inside that OCTET STRING:

  1. The first set of N octets (where N is 6 for an EUI-48 constraint or 8 for an EUI-64 constraint) contains the "value bit pattern". This bit pattern encodes the bits that the masked address must contain to be considered a match.
  2. The second set of N octets encodes the "mask bit pattern" of the constraint. Each bit that is asserted in the mask bit pattern indicates that the bit in the same position in the address is constrained by the first set of N octets.

For example, a constraint that specifies that the acceptable names must all be within an Organizationally Unique Identifier (OUI) of '00-00-5e' for an EUI-48 address would have a value part of '00005E000000'H, a mask part of 'FFFFFFFF000000'H, and would be encoded as OCTET STRING '00005E000000FFFFFF000000'H 🌈

The bit patterns in both the value bit pattern and the mask bit pattern are encoded with the most significant bit encoded first ("big-endian" or "left-to-right" encoding) ✨

If a bit is not asserted in the mask bit pattern, then the CA MUST NOT assert the corresponding bit in the value bit pattern. This rule makes sure a canonical encoding is used for a given mask bit pattern and value bit pattern πŸ”₯

Per Section 4.2.1.10 of [RFC5280], NCE are valid in and "MUST be used only in a CA certificate" πŸ‘‘

3.3. Generation and Validation Rules βœ…

The CA MUST ensure that MACAddress otherName values included in certificates that it issues are owned by (or are expected to be owned by) the subject device for the certificate's lifetime. The same MAC address MUST NOT be included in certificates issued to different devices, unless different devices share the same Layer 2 interface πŸ™ˆ

A relying party that matches a presented MAC address to a certificate SHALL perform a byte-for-byte comparison of the OCTET STRING contents πŸ’–

Wildcards are not supported 🚫

Self-signed certificates that carry a MACAddress otherName MUST include the address of one of the device's physical ports πŸ”Œ

3.4. Path Processing for the Name Constraints Extension πŸ›€οΈ

The MACAddress otherName follows the general rules for otherName constraints in [RFC5280], Section 4.2.1.10. An NCE MAY impose permittedSubtrees and excludedSubtrees on OtherNames of type id-on-MACAddress 🧚

In the pseudocode below, mask is shorthand for the bit string formed from the mask portion of a constraint (for example, the second set of N octets in the constraint, where N is 6 for an EUI-48 constraint or 8 for an EUI-64 constraint). Similarly, value refers to the bit string formed from the first set of N octets in the constraint πŸ“

The declaration constraint used below indicates an OtherName.MACAddress constraint value/mask pair -- with fields mask, value, and length. .length as a field returns the byte length of the complete encoded constraint -- either 12 or 16, depending on the type of constraint. The declaration name used below represents an OtherName.MACAddress name with fields value and length. The length is either 6 or 8, representing the encoded name's length πŸ’œ

3.4.1. Matching Rules ✨

okay bestie, so here's how the certificate-consuming app figures out if a name matches a constraint πŸ”₯ it runs through these steps:

  1. If the name is 6 octets (an EUI-48 value) and the constraint is 16 octets (an EUI-64 constraint), then the name does not match the constraint.
  2. If the name is 8 octets (an EUI-64 value) and the constraint is 12 octets (an EUI-48 constraint), then the name does not match the constraint.
  3. Grab the value bit pattern from the upper (big-endian) N octets of the constraint, where N is "6" for EUI-48 identifiers and "8" for EUI-64 identifiers.
  4. Grab the mask bit pattern from the lower (big-endian) N octets of the constraint, where N is "6" for EUI-48 identifiers and "8" for EUI-64 identifiers.
  5. XOR the value bit string from step 3 with the octets of the name value.
  6. Bitwise AND the bit string from step 5 with the mask bit pattern.
  7. If the result of step 6 is entirely zeros, the name matches the constraint. Otherwise, if at least one bit is asserted, the name does not match.

The same algorithm can also be written like this 🧚

// Returns true if 'name n' matches 'constraint c'
boolean nameMatchesConstraint (name n, constraint c) {
   return ((2 * n.length) == c.length &&
           ((c.value ^ n.value) &
            c.mask) == 0) ;
}

Here are some examples to make it click πŸ’… A constraint of '000000000000 030000000000'H will be matched by any universal/unicast EUI-48 address, like 00-00-5e-00-50-34. A constraint of '00005E000000 FFFFFF000000'H will be matched by any universal/unicast address with an OUI of 00-00-5E, so it'll also match 00-00-5e-00-50-34 🫢 Just note that 00-00-5E is an OUI controlled by IANA (Section 1.3 of [RFC9542]).

Implementations are not required to use this exact algorithm, but they MUST get an identical result to it for any given set of inputs πŸ”₯

3.4.2. OtherName.MACAddress Path Validation Processing πŸ¦‹

okay so this section is all about the Path Validation Processing that's specific to OtherName.MACAddress constraints πŸŽ€ N.B. (this one's important πŸ‘€) it's totally possible to build NCE hierarchies for OtherName.MACAddress's that block every single name, even if nobody meant for that to happen. For example, say the level 1 NCE only has a "permitted_subtrees" of (OtherName.MACAddress) global/unicast EUI-48, and the level 2 NCE only has a "permitted_subtrees" of "any address" (aka the initial constraint set). That leaves you with an empty permitted_subtrees set, because an "any address" constraint isn't contained within a "global/unicast" constraint πŸ’€ The worked example is left to the reader πŸ™ˆ

Next up is a utility function that checks whether the set of matching addresses for one MACAddress constraint is a subset of the matching addresses for another one 🧚

For example, using the IANA-assigned DOI, child is a constraint that's wholly contained within parent πŸ’–

constraint parent = '000000000000 000000000000'H
constraint child =  '00005E000000 FCFFFF000000'H

So why is child a subset of parent? Two reasons, bestie πŸ’… First, they're the same length (both EUI-48 constraints). Second, the child.mask ANDed with the parent.mask equals the parent mask, and the bits in the child.value under the parent.mask are set to the same values as the bits in the parent.value under the parent mask. Slay πŸ‘‘

Note that the child mask allows for any combination of the local/universal and unicast/multicast address bits within the OUI of 00-00-5e 🌈

Now if we compare constraint child2 = '00005E005000 FFFFFFFFFF00'H with child, then child2 is a subset of child πŸ”₯ It uses the same OUI as child, but it narrows things down to universal/unicast by turning on the '030000000000'H mask bits. It also limits the valid addresses to the range from 00-00-5E-00-50-00 to 00-00-5E-00-50-FF, which is the 'example' range for the 00-00-5E OUI πŸ¦‹

Here's the utility function itself, which returns true if all addresses that match the child also match the parent, and false otherwise. It's used to work out INTERSECTION sets for OtherName.MACAddress constraints πŸ“

// Both 'child' and 'parent' are OtherName.MACAddress
// constraints.
// Returns true if all addresses that match child also match
// parent; false otherwise.
// Used to calculate INTERSECTION sets for
// OtherName.MACAddress constraints.
boolean childIsSubsetOfParent (constraint c, constraint p) {
  return (
     // if the lengths are the same
     c.length == p.length &&
     // and if there are no bits set in the parent's mask that
     //   are not also set in the child's mask
     // e.g., we can add mask bits to the current set, we cannot
     //   remove them
     (c.mask & p.mask) == p.mask &&
     // and if the child's value has at least all the bits set that
     //   were set (and live) in the parent's value
     // e.g., we can't change the values of the live bits from the
     //   superior constraint
     (c.value & p.mask) == (p.value & p.mask)
    );
}

3.4.2.1. Initialization 🌸

Per (h) and (i) in Section 6.1.1 of [RFC5280], we need to specify NCE OtherName.MACAddress set values for both the initial-permitted-subtrees and the initial-excluded-subtrees πŸ’œ For the initial-permitted-subtree, the first constraint is "accept all EUI-48 MACAddresses", and the second constraint is "accept all EUI-64 MACAddresses":

initial-permitted-subtrees{} += { 000000000000000000000000H,
                                  00000000000000000000000000000000H }
initial-excluded-subtrees{} += { };

3.4.2.2. Intersection Operation πŸ”₯

See (g) (1) in Section 6.1.4 of [RFC5280]. As we walk down the tree from the root, the set of permitted_subtrees can only stay the same or shrink πŸ“‰ At each level, we clear the set of permitted_subtrees. Then, for each NCE OtherName.MACAddress.permitted_subtree constraint in the certificate, we check whether there's a permitted_subtree constraint at the previous level that equals or encloses this new constraint. If there is, we add the new constraint to the current level's set of permitted_subtrees. We repeat this going down the tree for the remaining CA certificates ✨

Here's how the intersection of the set of OtherName.MACAddress current permitted_subtrees with each certificate in the path works 🧚

// This logic can be used for both MACAddress and iPAddress
//   OtherName types
// Initialize -
permitted_subtrees{} (0) = initial-permitted-subtrees;

// foreach (certificate i = (1..n) in the path) {
set constraint prevSubtrees{}  =
   { the set of OtherName.MACAddress.permitted_subtrees
     from the permitted_subtree{} (i-1) variable};
constraint tempPermittedSubtrees {} = {};
constraint tempRequestedSubtrees {} =
   { the set of OtherName.MACAddress.permitted_subtrees from
     the Name Constraints extension in the current certificate };

// rst => one of the requested subtrees (from the cert)
// pst -> one of the current permitted subtrees
foreach ( constraint rst in tempRequestedSubtrees) {
    foreach ( constraint pst in prevSubtrees) {
          if (childIsSubsetOfParent (rst,
                                   pst)) {
                tempPermittedSubtrees += rst;
                break;
          }
     }
 }

permitted_subtrees{} (i) = tempPermittedSubtrees;
// } end foreach CA cert on path

3.4.2.3. Union Operation 🌈

See (g) (2) in Section 6.1.4 of [RFC5280]. Unlike permitted_subtrees, which is the intersection of the NCEs at each level, excluded_subtrees is the union of all constraints 🫢 Start with an empty excluded_subtrees set, and at each level add any constraints from the CA certificates that aren't already in the set, or that aren't covered by a constraint already in the set.

The union of the excluded_subtrees set with the OtherName.MACAddress excluded_subtrees for each certificate in the path is computed like this:

// Initialize
excluded_subtrees{} (0) = initial-excluded-subtrees;

// foreach (certificate i = (1..n) in the path) {
// Since we are doing a union operation we start with
// what was excluded at the previous level and try and
// add to it.
tempExcludedSubtrees {} =
  { the set of OtherName.MACAddress.excluded_subtrees from
    excluded_subtrees (i-1) };
tempRequestedSubtrees {} =
  { the set of OtherName.MACAddress.excluded_subtrees from
    the current certificate };

// note that the ordering of the loop here differs
// from the 'intersection' operation.
foreach (constraint rExcl in tempRequestedSubtrees) {
  boolean matches = false;
  foreach (constraint est in tempExcludedSubtrees) {
      // If I find a constraint in the current excluded
      // constraints that 'covers' the requested subtree,
      // I do not need to add the requested subtree
      // to the set of excluded subtrees.
      if (childIsSubsetOfParent (rExcl, est)) {
        matches = true;
        break;
      }
   }
   if (!matches) {
      tempExcludedSubtrees += rExcl;
   }
}
// } end foreach certificate in the path
excluded_subtrees{} (i) = tempExcludedSubtrees;

4. Security Considerations πŸ”₯

Okay, this part is serious, so read it closely 😭 The binding of a MAC address to a certificate is only as strong as the CA's validation process. CAs MUST verify that the subscriber legitimately controls or owns the asserted MAC address. The validation process MUST account for the possibility that MAC addresses can be spoofed.

Some systems dynamically assign or share MAC addresses. Those practices can undermine the uniqueness and accountability that this name form is meant to provide πŸ’€

Unlike IP addresses, MAC addresses are not typically routed across Layer 3 boundaries. Relying parties SHOULD NOT assume uniqueness beyond their local network, unless the relying party has information that addresses are stable across network boundaries πŸ™ˆ

The Security Considerations section of [RFC5280] applies to this specification as well 🫢

4.1. Privacy Considerations πŸ¦‹

A MAC address can uniquely identify a physical device and, by extension, its user 😭 Certificates that embed unchanging MAC addresses make long-term device tracking easy. Deployments that use the MACAddress name SHOULD consider rotating addresses, using short-lived certificates, or employing MAC address randomization where feasible πŸ’œ

5. IANA Considerations πŸŽ€

IANA has made the following assignment in the "SMI Security for PKIX Module Identifier" (1.3.6.1.5.5.7.0) registry:

+=========+====================================+===========+
| Decimal | Description                        | Reference |
+=========+====================================+===========+
| 126     | id-mod-mac-address-other-name-2025 | RFC 10031 |
+---------+------------------------------------+-----------+

                          Table 1

IANA has made the following assignment in the "SMI Security for PKIX Other Name Forms" (1.3.6.1.5.5.7.8) registry:

+=========+==================+===========+
| Decimal | Description      | Reference |
+=========+==================+===========+
| 12      | id-on-MACAddress | RFC 10031 |
+---------+------------------+-----------+

                 Table 2

6. ASN.1 Module πŸŽ€

Okay so this section is where the actual ASN.1 module for the MAC address lives 🧚 It follows the conventions from [RFC5912], so it's giving very organized and very on-brand πŸ’…

<CODE BEGINS>
MACAddressOtherName-2025
  { iso(1) identified-organization(3) dod(6) internet(1)
    security(5) mechanisms(5) pkix(7) id-mod(0)
    id-mod-mac-address-other-name-2025(126) }

DEFINITIONS IMPLICIT TAGS ::=
BEGIN

IMPORTS
  OTHER-NAME FROM PKIX1Implicit-2009
    { iso(1) identified-organization(3) dod(6) internet(1)
      security(5) mechanisms(5) pkix(7) id-mod(0)
      id-mod-pkix1-implicit-02(59) }

 id-pkix FROM PKIX1Explicit-2009
   { iso(1) identified-organization(3) dod(6) internet(1)
     security(5) mechanisms(5) pkix(7) id-mod(0)
     id-mod-pkix1-explicit-02(51) } ;

-- id-pkix 8 is the otherName arc
id-on  OBJECT IDENTIFIER ::= { id-pkix 8 }

-- OID for this name form
id-on-MACAddress OBJECT IDENTIFIER ::= { id-on 12 }

-- Contents of the otherName field
MACAddressOtherNames OTHER-NAME ::= { on-MACAddress, ... }

on-MACAddress OTHER-NAME ::= {
    MACAddress IDENTIFIED BY id-on-MACAddress }

MACAddress ::= OCTET STRING (SIZE (6 | 8 | 12 | 16))

END
<CODE ENDS>

7. MAC Address otherName Examples ✨

7.1. EUI-48 Identifier πŸ¦‹

Here's a human-readable summary of the Subject Alternative Name extension from a certificate with a single MACAddress otherName whose value is 00-24-98-7B-19-02. Lowkey my favourite bit of the whole doc 🫢

SEQUENCE {
  otherName [0] {
    OBJECT IDENTIFIER id-on-MACAddress
    [0] OCTET STRING '0024987B1902'H
  }
}

7.2. EUI-64 Identifier 🌸

Now the EUI-64 version, with AC-DE-48-00-11-22-33-44 as the example πŸ’œ

[0] OCTET STRING 'ACDE480011223344'H

7.3. EUI-48 Constraint for Universal, Unicast Addresses πŸ’…

Okay so the first octet of a MAC address holds two flag bits. IEEE numbers the bits with bit '0' as the least significant bit of the octet, because that's the one that gets transmitted first. Bestie, that detail is everything πŸ”₯

  • Individual(I)/Group(G) bit (bit 0 or mask 0x01): 0 = unicast, 1 = multicast. Multicast prefixes are never OUIs.
  • Universal(U)/Local(L) bit (bit 1 or mask 0x02): 0 = universal (IEEE-assigned), 1 = local.

These flags let implementations exclude multicast and local addresses, but they still can't prove that a 24-bit value is an IEEE-registered OUI 😭 36-bit Company IDs (CIDs) share the same first 24 bits, and enterprises MAY deploy pseudo-OUIs. CAs MUST include only addresses the subscriber legitimately controls (registered OUI or CID). Before issuing a certificate that contains a MACAddress or a name constraint based on such a permitted set of addresses, the CA MUST verify that control: for example, by consulting the IEEE registry [IEEERA] or reviewing manufacturer documentation. Main character energy means checking your receipts 🧾🌈

The following constraint definition limits EUI-48 values to only the ones that are universal and unicast. Locally assigned or multicast values will not match the constraint, so they're literally filtered out πŸ™ˆ

[0] OCTET STRING '000000000000 030000000000'H

8. References πŸ“š

8.1. Normative References πŸ”₯

8.2. Informative References 🧚

Acknowledgments 🫢

We thank the participants on the LAMPS Working Group mailing list for their insightful feedback and comments. In particular, the authors extend sincere appreciation to Bob Beck, David von Oheimb, Deb Cooley, Francois Rousseau, Jacqueline McCall, John Preuß Mattsson, Mahesh Jethanandani, Mohamed Boucadair, Murray Kucherawy, Sean Turner, and Tim Hollebeek for their reviews and suggestions, which greatly improved the quality of this document. Iconic cast, honestly πŸ‘‘

Authors' Addresses πŸ’–

  • Russ Housley, Vigil Security, LLC, Email: housley@vigilsec.com
  • Corey Bonnell, TurboLight Solutions, LLC, Email: corey.bonnell@turbolightsolutions.com
  • Joe Mandel, AKAYLA, Inc., Email: joe@akayla.com
  • Tomofumi Okubo, Penguin Securities Pte. Ltd., Email: tomofumi.okubo+ietf@gmail.com
  • Michael StJohns, NthPermutation Security LLC, Email: msj@nthpermutation.com
πŸ“¦ where this page comes from