On 30.4.2014 18:19, Petr Spacek wrote:
following text summarizes schema & DIT layout for DNSSEC key storage in LDAP.

I have added object classes and default values for attributes I consider important. This is final proposal for implementation. Please review it ASAP.

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?

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

dn: ipk11Label=zone1_keyid123_public, cn=keys, cn=sec, cn=dns, dc=example
objectClass: ipk11Object
objectClass: ipk11PublicKey
objectClass: ipaPublicKeyObject
ipk11UniqueId: <UUID>
ipk11Label: zone1_keyid123_public
ipk11Wrap: FALSE
ipk11Verify: TRUE
ipaPublicKey: <public key>

dn: ipk11Label=zone1_keyid123_private, cn=keys, cn=sec, cn=dns, dc=example
objectClass: ipk11Object
objectClass: ipk11PrivateKey
objectClass: ipaPrivateKeyObject
objectClass: ipaWrappedKey
ipaWrappingKey:ipk11Label=dnssec_m1,cn=master,cn=keys,cn=sec,cn=dns,dc=example
ipk11Sign: TRUE
ipk11Decrypt: FALSE
ipk11Unwrap: FALSE
ipaPrivateKey: <blob encrypted with DNSSEC master key>


  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.)
This will be sorted out in separate thread.


  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

- Please note that private part of this key is stored on disk.

dn: ipk11Label=wrapkey_replica1,cn=DNS,cn=<replica FQDN>,cn=masters,cn=ipa,cn=etc,dc=example
objectClass: ipk11Object
objectClass: ipk11PublicKey
objectClass: ipaPublicKeyObject
ipk11UniqueId: <UUID>
ipk11Label: wrapkey_replica1
ipk11Wrap: TRUE
ipk11Encrypt: FALSE
ipk11Verify: FALSE
ipaPublicKey: <public key>

  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.

dn: ipk11Label=dnssec_m1, cn=master, cn=keys, cn=sec, cn=dns, dc=example
objectClass: ipk11Object
objectClass: ipk11SecretKey
objectClass: ipaWrappedKey
objectClass: ipaSecretKeyObject
ipk11UniqueId: <UUID>
ipk11Label: dnssec_m1
ipk11Wrap: TRUE
ipk11UnWrap: TRUE
ipk11Encrypt: FALSE
ipk11Decrypt: FALSE
ipk11Sign: FALSE
ipk11Verify: FALSE
ipaWrappingAlgo: <algorithm used for key wrapping>
ipaSecretKeyWrappedData: <encrypted blob for replica-1>
ipaSecretKeyWrappedData: <encrypted blob for replica-2>
ipaWrappingKey: <DN of replica-1 public key>
ipaWrappingKey: <DN of replica-2 public key>

Petr^2 Spacek

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

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to