db7763ca7b
Status:
- And it works!
- We have an extensive test based on decoding a rich EK certficate.
This test exercises all of:
- decoding
- encoding with and without decoded open types
- copying of decoded values with decoded open types
- freeing of decoded values with decoded open types
Valgrind finds no memory errors.
- Added a manual page for the compiler.
- rfc2459.asn1 now has all three primary PKIX types that we care about
defined as in RFC5912, with IOS constraints and parameterization:
- `Extension` (embeds open type in an `OCTET STRING`)
- `OtherName` (embeds open type in an `ANY`-like type)
- `SingleAttribute` (embeds open type in an `ANY`-like type)
- `AttributeSet` (embeds open type in a `SET OF ANY`-like type)
All of these use OIDs as the open type type ID field, but integer
open type type ID fields are also supported (and needed, for
Kerberos).
That will cover every typed hole pattern in all our ASN.1 modules.
With this we'll be able to automatically and recursively decode
through all subject DN attributes even when the subject DN is a
directoryName SAN, and subjectDirectoryAttributes, and all
extensions, and all SANs, and all authorization-data elements, and
PA-data, and...
We're not really using `SingleAttribute` and `AttributeSet` yet
because various changes are needed in `lib/hx509` for that.
- `asn1_compile` builds and recognizes the subset of X.681/682/683 that
we need for, and now use in, rfc2459.asn1. It builds the necessary
AST, generates the correct C types, and generates templating for
object sets and open types!
- See READMEs for details.
- Codegen backend not tested; I won't make it implement automatic open
type handling, but it should at least not crash by substituting
`heim_any` for open types not embedded in `OCTET STRING`.
- We're _really_ starting to have problems with the ITU-T ASN.1
grammar and our version of it...
Type names have to start with upper-case, value names with
lower-case, but it's not enough to disambiguate.
The fact the we've allowed value and type names to violate their
respective start-with case rules is causing us trouble now that we're
adding grammar from X.681/682/683, and we're going to have to undo
that.
In preparation for that I'm capitalizing the `heim_any` and
`heim_any_set` types, and doing some additional cleanup, which
requires changes to other parts of Heimdal (all in this same commit
for now).
Problems we have because of this:
- We cannot IMPORT values into modules because we have no idea if a
symbol being imported refers to a value or a type because the only
clue we would have is the symbol's name, so we assume IMPORTed
symbols are for types.
This means we can't import OIDs, for example, which is super
annoying.
One thing we might be able to do here is mark imported symbols as
being of an undetermined-but-not-undefined type, then coerce the
symbol's type the first time it's used in a context where its type
is inferred as type, value, object, object set, or class. (Though
since we don't generate C symbols for objects or classes, we won't
be able to import them, especially since we need to know them at
compile time and cannot defer their handling to link- or
run-time.)
- The `NULL` type name, and the `NULL` value name now cause two
reduce/reduce conflicts via the `FieldSetting` production.
- Various shift/reduce conflicts involving `NULL` values in
non-top-level contexts (in constraints, for example).
- Currently I have a bug where to disambiguate the grammar I have a
CLASS_IDENTIFIER token that is all caps, while TYPE_IDENTIFIER must
start with a capital but not be all caps, but this breaks Kerberos
since all its types are all capitalized -- oof!
To fix this I made it so class names have to be all caps and
start with an underscore (ick).
TBD:
- Check all the XXX comments and address them
- Apply this treatment to Kerberos! Automatic handling of authz-data
sounds useful :)
- Apply this treatment to PKCS#10 (CSRs) and other ASN.1 modules too.
- Replace various bits of code in `lib/hx509/` with uses of this
feature.
- Add JER.
- Enhance `hxtool` and `asn1_print`.
Getting there!
249 lines
8.3 KiB
Plaintext
249 lines
8.3 KiB
Plaintext
-- $Id$
|
|
HDB DEFINITIONS ::=
|
|
BEGIN
|
|
|
|
IMPORTS EncryptionKey, KerberosTime, Principal FROM krb5;
|
|
|
|
HDB_DB_FORMAT INTEGER ::= 2 -- format of database,
|
|
-- update when making changes
|
|
|
|
-- these must have the same value as the pa-* counterparts
|
|
hdb-pw-salt INTEGER ::= 3
|
|
hdb-afs3-salt INTEGER ::= 10
|
|
|
|
Salt ::= SEQUENCE {
|
|
type[0] INTEGER (0..4294967295),
|
|
salt[1] OCTET STRING,
|
|
opaque[2] OCTET STRING OPTIONAL
|
|
}
|
|
|
|
Key ::= SEQUENCE {
|
|
mkvno[0] INTEGER (0..4294967295) OPTIONAL, -- master key version number
|
|
key[1] EncryptionKey,
|
|
salt[2] Salt OPTIONAL
|
|
}
|
|
|
|
Event ::= SEQUENCE {
|
|
time[0] KerberosTime,
|
|
principal[1] Principal OPTIONAL
|
|
}
|
|
|
|
HDBFlags ::= BIT STRING {
|
|
initial(0), -- require as-req
|
|
forwardable(1), -- may issue forwardable
|
|
proxiable(2), -- may issue proxiable
|
|
renewable(3), -- may issue renewable
|
|
postdate(4), -- may issue postdatable
|
|
server(5), -- may be server
|
|
client(6), -- may be client
|
|
invalid(7), -- entry is invalid
|
|
require-preauth(8), -- must use preauth
|
|
change-pw(9), -- change password service
|
|
require-hwauth(10), -- must use hwauth
|
|
ok-as-delegate(11), -- as in TicketFlags
|
|
user-to-user(12), -- may use user-to-user auth
|
|
immutable(13), -- may not be deleted
|
|
trusted-for-delegation(14), -- Trusted to print forwardabled tickets
|
|
allow-kerberos4(15), -- Allow Kerberos 4 requests
|
|
allow-digest(16), -- Allow digest requests
|
|
locked-out(17), -- Account is locked out,
|
|
-- authentication will be denied
|
|
require-pwchange(18), -- require a passwd change
|
|
|
|
materialize(19), -- store even if within virtual namespace
|
|
virtual-keys(20), -- entry stored; keys mostly derived
|
|
virtual(21), -- entry not stored; keys always derived
|
|
|
|
force-canonicalize(30), -- force the KDC to return the canonical
|
|
-- principal irrespective of the setting
|
|
-- of the canonicalize KDC option
|
|
do-not-store(31) -- Not to be modified and stored in HDB
|
|
}
|
|
|
|
GENERATION ::= SEQUENCE {
|
|
time[0] KerberosTime, -- timestamp
|
|
usec[1] INTEGER (0..4294967295), -- microseconds
|
|
gen[2] INTEGER (0..4294967295) -- generation number
|
|
}
|
|
|
|
HDB-Ext-PKINIT-acl ::= SEQUENCE OF SEQUENCE {
|
|
subject[0] UTF8String,
|
|
issuer[1] UTF8String OPTIONAL,
|
|
anchor[2] UTF8String OPTIONAL
|
|
}
|
|
|
|
HDB-Ext-PKINIT-hash ::= SEQUENCE OF SEQUENCE {
|
|
digest-type[0] OBJECT IDENTIFIER,
|
|
digest[1] OCTET STRING
|
|
}
|
|
|
|
HDB-Ext-PKINIT-cert ::= SEQUENCE OF SEQUENCE {
|
|
cert[0] OCTET STRING
|
|
}
|
|
|
|
HDB-Ext-Constrained-delegation-acl ::= SEQUENCE OF Principal
|
|
|
|
-- hdb-ext-referrals ::= PA-SERVER-REFERRAL-DATA
|
|
|
|
HDB-Ext-Lan-Manager-OWF ::= OCTET STRING
|
|
|
|
HDB-Ext-Password ::= SEQUENCE {
|
|
mkvno[0] INTEGER (0..4294967295) OPTIONAL, -- master key version number
|
|
password OCTET STRING
|
|
}
|
|
|
|
HDB-Ext-Aliases ::= SEQUENCE {
|
|
case-insensitive[0] BOOLEAN, -- case insensitive name allowed
|
|
aliases[1] SEQUENCE OF Principal -- all names, inc primary
|
|
}
|
|
|
|
Keys ::= SEQUENCE OF Key
|
|
|
|
HDB_keyset ::= SEQUENCE {
|
|
kvno[0] INTEGER (0..4294967295),
|
|
keys[1] Keys,
|
|
set-time[2] KerberosTime OPTIONAL, -- time this keyset was created/set
|
|
...
|
|
}
|
|
|
|
HDB-Ext-KeySet ::= SEQUENCE OF HDB_keyset
|
|
|
|
--
|
|
-- We need a function of current (or given, but it will always be current) time
|
|
-- and a base hdb_entry or its HDB-Ext-KeyRotation and service ticket lifetime,
|
|
-- that outputs a sequence of {kvno, set_time, max_life} representing past keys
|
|
-- (up to one per past and current KeyRotation), current keys (for the current
|
|
-- KeyRotation), up to one future key for the current KeyRotation, and up to
|
|
-- one future key for the _next_ (future) KeyRotation if there is one.
|
|
--
|
|
-- We have to impose constraints on new KeyRotation elements of
|
|
-- HDB-Ext-KeyRotation.
|
|
--
|
|
-- So virtual keysets (keytabs) will contain:
|
|
--
|
|
-- - up to one past keyset for all KeyRotation periods that are "applicable"
|
|
-- - the current keyset for all KeyRotation periods that are "applicable"
|
|
-- - up to one future keyset for all KeyRotation periods that are "applicable"
|
|
--
|
|
-- An applicable KeyRotation period is:
|
|
--
|
|
-- - the KeyRotation whose `epoch` is a) in the past and b) nearest to the
|
|
-- current time - we call this the current KeyRotation
|
|
-- - a KeyRotation whose `epoch` is nearest but in the past of the current
|
|
-- one
|
|
-- - a KeyRotation whose `epoch` is nearest but in the future of the current
|
|
-- one
|
|
--
|
|
-- A service principal's max ticket life will be bounded by half the current
|
|
-- key rotation period.
|
|
--
|
|
-- Note: There can be more than one applicable past KeyRotation, and more than
|
|
-- one applicable KeyRotation. We might not want to permit this.
|
|
-- However, it's probably easier to permit it, though we might not test
|
|
-- end-to-end.
|
|
--
|
|
-- Testing:
|
|
--
|
|
-- - We should have standalone unit tests for all these pure functions.
|
|
--
|
|
-- - We should have a test that uses kadm5 and GSS to test against a KDC using
|
|
-- small key rotation periods on the order of seconds, with back-off in case
|
|
-- of losing a race condition.
|
|
--
|
|
KeyRotationFlags ::= BIT STRING {
|
|
deleted(0), -- if set on a materialized principal, this will mean
|
|
-- the principal does not exist
|
|
-- if set on a namespace, this will mean that
|
|
-- only materialized principal below it exist
|
|
parent(1) -- if set on a materialized principal, this will mean
|
|
-- that the keys for kvnos in this KeyRotation spec
|
|
-- will be derived from the parent's base keys and
|
|
-- corresponding KeyRotation spec
|
|
-- if set on a namespace, this flag will be ignored
|
|
-- (or we could support nested namespaces?)
|
|
}
|
|
KeyRotation ::= SEQUENCE {
|
|
-- base-kvno is always computed at set time and set for the principal,
|
|
-- and is never subject to admin choice. The base-kvno is that of the
|
|
-- current kvno at that period's `from` given the previous period.
|
|
--
|
|
-- Also, insertion of KeyRotation elements before existing ones (in
|
|
-- time) is never permitted, and all new KeyRotation elements must be
|
|
-- in the future relative to existing ones.
|
|
--
|
|
-- HDB-Ext-KeyRotation will always be sorted (as stored) by `from`, in
|
|
-- descending order.
|
|
--
|
|
-- Max service ticket lifetime will be constrained to no more than half
|
|
-- the period of the the applicable KeyRotation elements.
|
|
--
|
|
flags[0] KeyRotationFlags,
|
|
epoch[1] KerberosTime, -- start of this period
|
|
period[2] INTEGER(0..4294967295), -- key rotation seconds
|
|
base-kvno[3] INTEGER(0..4294967295), -- starting from this kvno
|
|
base-key-kvno[4]INTEGER(0..4294967295), -- kvno of base-key
|
|
...
|
|
}
|
|
|
|
HDB-Ext-KeyRotation ::= SEQUENCE SIZE (1..3) OF KeyRotation
|
|
|
|
HDB-extension ::= SEQUENCE {
|
|
mandatory[0] BOOLEAN, -- kdc MUST understand this extension,
|
|
-- if not the whole entry must
|
|
-- be rejected
|
|
data[1] CHOICE {
|
|
pkinit-acl[0] HDB-Ext-PKINIT-acl,
|
|
pkinit-cert-hash[1] HDB-Ext-PKINIT-hash,
|
|
allowed-to-delegate-to[2] HDB-Ext-Constrained-delegation-acl,
|
|
-- referral-info[3] HDB-Ext-Referrals,
|
|
lm-owf[4] HDB-Ext-Lan-Manager-OWF,
|
|
password[5] HDB-Ext-Password,
|
|
aliases[6] HDB-Ext-Aliases,
|
|
last-pw-change[7] KerberosTime,
|
|
pkinit-cert[8] HDB-Ext-PKINIT-cert,
|
|
hist-keys[9] HDB-Ext-KeySet,
|
|
hist-kvno-diff-clnt[10] INTEGER (0..4294967295),
|
|
hist-kvno-diff-svc[11] INTEGER (0..4294967295),
|
|
policy[12] UTF8String,
|
|
principal-id[13] INTEGER(-9223372036854775808..9223372036854775807),
|
|
key-rotation[14] HDB-Ext-KeyRotation,
|
|
krb5-config[15] OCTET STRING,
|
|
...
|
|
},
|
|
...
|
|
}
|
|
|
|
HDB-extensions ::= SEQUENCE OF HDB-extension
|
|
|
|
-- Just for convenience, for encoding this as TL data in lib/kadm5
|
|
HDB-EncTypeList ::= SEQUENCE OF INTEGER (0..4294967295)
|
|
|
|
HDB_entry ::= SEQUENCE {
|
|
principal[0] Principal OPTIONAL, -- this is optional only
|
|
-- for compatibility with libkrb5
|
|
kvno[1] INTEGER (0..4294967295),
|
|
keys[2] Keys,
|
|
created-by[3] Event,
|
|
modified-by[4] Event OPTIONAL,
|
|
valid-start[5] KerberosTime OPTIONAL,
|
|
valid-end[6] KerberosTime OPTIONAL,
|
|
pw-end[7] KerberosTime OPTIONAL,
|
|
max-life[8] INTEGER (0..4294967295) OPTIONAL,
|
|
max-renew[9] INTEGER (0..4294967295) OPTIONAL,
|
|
flags[10] HDBFlags,
|
|
etypes[11] HDB-EncTypeList OPTIONAL,
|
|
generation[12] GENERATION OPTIONAL,
|
|
extensions[13] HDB-extensions OPTIONAL
|
|
}
|
|
|
|
HDB_entry_alias ::= [APPLICATION 0] SEQUENCE {
|
|
principal[0] Principal OPTIONAL
|
|
}
|
|
|
|
HDB-EntryOrAlias ::= CHOICE {
|
|
entry HDB_entry,
|
|
alias HDB_entry_alias
|
|
}
|
|
|
|
END
|