[Freeipa-devel] LDAP schema for DNSSEC keys

Ludwig Krispenz lkrispen at redhat.com
Mon May 5 08:45:04 UTC 2014


Hi Petr,

On 05/02/2014 08:48 PM, Petr Spacek wrote:
> On 1.5.2014 16:10, Rich Megginson wrote:
>> On 04/30/2014 10:19 AM, Petr Spacek wrote:
>>> Hello list,
>>>
>>> following text summarizes schema & DIT layout for DNSSEC key storage 
>>> in LDAP.
>>>
>>> This is subset of full PKCS#11 schema [0]. It stores bare keys with few
>>> metadata attributes when necessary.
>>>
>>> The intention is to make transition to full PKCS#11-in-LDAP schema 
>>> [0] as
>>> easy as possible. This transition should happen in next minor 
>>> version of
>>> FreeIPA.
>>>
>>> In theory, the transition should be just adding few object classes to
>>> existing objects and populating few new metadata attributes. Related 
>>> object
>>> classes are marked below with "(in long-term)".
>>>
>>> Please comment on it soon. We want to implement it ASAP :-)
>>>
>>>
>>> DNSSEC key
>>> ==========
>>> - Asymmetric
>>> - Private key is stored in LDAP as encrypted PKCS#8 blob
>>> - Public key is published in LDAP
>>> - Encrypted with symmetric "DNSSEC master key" (see below)
>>> - Private key - represented as LDAP object with object classes:
>>> ipaEPrivateKey  [1] # encrypted data
>>> ipaWrappedKey   [2] # pointer to master key, outside scope of pure 
>>> PKCS#11
>>> ipk11PrivateKey [3] (in long-term) # PKCS#11 metadata
>>> - Public key - represented as LDAP object with object classes:
>>> ipaPublicKey    [1] # public key data
>>> ipk11PublicKey  [3] (in long-term) # PKCS#11 metadata
>>>
>>>
>>> Master key
>>> ==========
>>> - Symmetric
>>> - Stored in LDAP as encrypted blob
>>> - Encrypted with asymmetric "replica key" (see below)
>>> - 1 replica = 1 blob, n replicas = n blobs encrypted with different 
>>> keys
>>> - A replica uses it's own key for master key en/decryption
>>> - Represented as LDAP object with object classes:
>>> ipaESecretKey  [1]
>>> ipk11SecretKey [3] (in long-term)
>>>
>>> Replica key
>>> ===========
>>> - Asymmetric
>>> - Private key is stored on replica's disk only
>>> - Public key for all replicas is stored in LDAP
>>> - Represented as LDAP object with object classes:
>>> ipaPublicKey   [1]
>>> ipk11PublicKey [3] (in long-term)
>>>
>>>
>>> DIT layout
>>> ==========
>>>  DNSSEC key material
>>>  -------------------
>>>  - Container: cn=keys, cn=sec, cn=dns, dc=example
>>>  - Private and public keys are stored as separate objects to 
>>> accommodate all
>>> PKCS#11 metadata.
>>>  - We need to decide about object naming:
>>>   - One obvious option for RDN is to use uniqueID but I don't like 
>>> it. It is
>>> hard to read for humans.
>>>   - Other option is to use uniqueID+PKCS#11 label or other 
>>> attributes to
>>> make it more readable. Can we use multi-valued RDN? If not, why? 
>>> What are
>>> technical reasons behind it?
>>
>> I would encourage you not to use multi-valued RDNs.  There aren't any
>> technical reasons - multi-valued RDNs are part of the LDAP standards 
>> and all
>> conforming LDAP implementations must support them.  However, they are 
>> hard to
>> deal with - you _must_ have some sort of DN class/api on the client 
>> side to
>> handle them, and not all clients do - many clients expect to be able 
>> to just
>> do dnstr.lower() == dnstr2.lower() or possibly do simple escaping.
>>
>> As far as being human readable - the whole goal is that humans 
>> _never_ have to
>> look at a DN.  If humans have to look at and understand a DN to 
>> accomplish a
>> task, then we have failed.
> I agree, users should not see them. I want to make life easier for 
> administrators and developers *debugging* it.
>
> I'm facing UUIDs-only logs and database in oVirt for more than year 
> now and I can tell you that it is horrible, horrible, horrible. It is 
> PITA when I have to debug something in oVirt because I have to search 
> for UUIDs all the time. I want to scream and jump out of the window 
> when I see single log line with 4 or more different UUIDs... :-)
>
>> Has the DogTag team reviewed this proposal?  Their data storage and 
>> workflows
>> are similar.
> That is very good point! Nathan, could somebody from DS team (maybe 
> somebody involved in Password Vault) review this "vault without Vault"?
>
> Thank you!
>
>>> It is question if we like:
>>>  nsUniqID = 0b0b7e53-957d11e3-a51dc0e5-9a05ecda
>>>  nsUniqID = 8ae4190d-957a11e3-a51dc0e5-9a05ecda
>>> more than:
>>>  ipk11Label=meaningful_label+ipk11Private=TRUE
>>>  ipk11Label=meaningful_label+ipk11Private=FALSE
there are two goals for choosing the naming attribute(s): they have to 
be unique in a level of the DIT and they should be meaningful/readable. 
I agree with Rich that technically nothing excludes multi-valued rdns, 
but could make things complicated for clients and in my opinion it does 
not increase readability.
In your case:
- are there really two entries with the same ipk11label, on private one 
not ? not all info has to be in the rdn, so you could use ipk11label as 
naming attribute
- couldn't you just use an other attribute as anming attr where you are 
free to put in what you want eg cn="<ipk11labe>(True)"
- we did define an ipk11uniquid to be used as naming attr for storage 
objects, but there are no definitions on its structure, you could use it 
as you like as long as it is unique (could be unique and meaningful and 
readable)
>>>
>>>  DNSSEC key metadata
>>>  -------------------
>>>  - Container (per-zone): cn=keys, idnsname=example.net, cn=dns
>>>  - Key metadata can be linked to key material via DN or ipk11Id.
>>>  - This allows key sharing between zones.
>>> (DNSSEC-metadata will be specified later. That is not important for key
>>> storage.)
>>>
>>>  Replica public keys
>>>  -------------------
>>>  - Container: cn=DNS,cn=<replica 
>>> FQDN>,cn=masters,cn=ipa,cn=etc,dc=example
>>>   - or it's child object like cn=wrappingKey
>>>
>>>  Master keys
>>>  -----------
>>>  - Container: cn=master, cn=keys, cn=sec, cn=dns, dc=example
>>>  - Single key = single object.
>>>  - We can use ipk11Label or ipk11Id for naming:
>>>  ipk11Label=dnssecMaster1, ipk11Label=dnssecMaster2, etc.
>>>
>>>
>>> Work flows
>>> ==========
>>>  Read DNSSEC private key
>>>  -----------------------
>>>   1) read DNSSEC private key from LDAP
>>>   2) ipaWrappedKey objectClass is present - key is encrypted
>>>   3) read master key denoted by ipaWrappingKey attribute in DNSSEC 
>>> key object
>>>   4) use local replica key to decrypt master key
>>>   5) use decrypted master key to decrypt DNSSEC private key
>>>
>>>  Add DNSSEC private key
>>>  ----------------------
>>>   1) use local replica key to decrypt master key
>>>   2) encrypt DNSSEC private key with master key
>>>   3) add ipaWrappingKey attribute pointing to master key
>>>   4) store encrypted blob in a new LDAP object
>>>
>>>  Add a replica
>>>  -------------
>>>  ipa-replica-prepare:
>>>   1) generate a new replica-key pair for the new replica
>>>   2) store key pair to replica-file (don't scream yet :-)
>>>   4) add public key for the new replica to LDAP
>>>   3) fetch master key from LDAP
>>>   4) encrypt master key with new replica public key
>>>   5) store resulting master key blob to LDAP
>>>  ipa-replica-install:
>>>   6) generate a new replica-key pair (!)
>>>   7) store new public key to LDAP
>>>   8) remove old public key (from replica-file) from LDAP
>>>   9) fetch master key
>>>  10) decrypt master key using old private key (from replica-file)
>>>  11) encrypt master key using new private key (generated locally)
>>>  12) replace old master key blob in LDAP with new blob (from step 11)
>>>
>>>  Delete a replica
>>>  ----------------
>>> This is the tricky part. New master key has to be generated on some 
>>> other
>>> replica. What should we do if the ipa-replica-manage command was run on
>>> deleted replica?
>>>
>>> I propose to split replica master key roll-over to two phases:
>>>  Any machine in IPA domain (including to-be deleted replica):
>>>   1) Delete public key associated with replica from LDAP
>>>   2) Flip a bit in master key metadata and say "this key needs to be
>>> re-generated"
>>>      (Maybe we can disable ipk11Wrap boolean to indicate that this key
>>> should not be used for key wrapping.)
>>>
>>>  Remaining replicas:
>>>   3) Periodically check that master key is obsolete
>>>   4) Wait for (random period of time) to limit probability of collision
>>>   5) Check that master key is really obsolete and new one is not 
>>> present
>>>   6) Generate a new master key
>>>   7) Encrypt new master key with all replica-public-keys stored in LDAP
>>>   8) Store new master key blobs to a new LDAP object
>>>      (Conflicts are not a problem up to now because we are not 
>>> deleting old
>>> key. In worst case, we will have multiple new master keys.)
>>> *What should we do now?*
>>>   9) ??? Re-encrypt all DNSSEC keys with a new master key? (What if 
>>> we have
>>> write conflict now?)
>>>      ??? Let old keys there and wait until key rotation mechanism 
>>> replaces
>>> all old DNSSEC keys with new DNSSEC keys encrypted with a new master 
>>> key (~
>>> one year)?
>>>  10) Old master key can be deleted when no other object is 
>>> referencing to it.
>>>
>>>
>>> Congratulations to people who reached this line and didn't skip 
>>> anything :-)
>>>
>>> [0] http://www.freeipa.org/page/V4/PKCS11_in_LDAP/Schema
>>> [1] 
>>> http://www.freeipa.org/page/V4/PKCS11_in_LDAP/Schema#Encoded_key_data_2
>>> [2]
>>> http://www.freeipa.org/page/V4/PKCS11_in_LDAP/Schema#FreeIPA_specifics_-_key_wrapping 
>>>
>>>
>>> [3] 
>>> http://www.freeipa.org/page/V4/PKCS11_in_LDAP/Schema#Storage_objects
>




More information about the Freeipa-devel mailing list