001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2016 ForgeRock AS.
015 */
016package org.forgerock.opendj.security;
017
018import static java.util.Arrays.asList;
019import static java.util.Collections.unmodifiableSet;
020import static org.forgerock.opendj.ldap.schema.Schema.getCoreSchema;
021
022import java.io.IOException;
023import java.io.InputStream;
024import java.net.URL;
025import java.util.LinkedHashSet;
026import java.util.Set;
027
028import org.forgerock.opendj.ldap.schema.AttributeType;
029import org.forgerock.opendj.ldap.schema.ObjectClass;
030import org.forgerock.opendj.ldap.schema.Schema;
031import org.forgerock.opendj.ldap.schema.SchemaBuilder;
032import org.forgerock.opendj.ldif.LDIFEntryReader;
033
034/** Utility methods for accessing the LDAP schema elements required in order to support the OpenDJ security provider. */
035public final class OpenDJProviderSchema {
036    // Minimal schema for required for interacting with the LDAP key store.
037    private static final URL SCHEMA_LDIF_URL = OpenDJProviderSchema.class.getResource("03-keystore.ldif");
038    static final Schema SCHEMA;
039    private static final Set<ObjectClass> OBJECT_CLASSES;
040    private static final Set<AttributeType> ATTRIBUTE_TYPES;
041    // Object classes.
042    static final String OC_KEY_STORE_OBJECT = "ds-keystore-object";
043    static final String OC_TRUSTED_CERTIFICATE = "ds-keystore-trusted-certificate";
044    static final String OC_PRIVATE_KEY = "ds-keystore-private-key";
045    static final String OC_SECRET_KEY = "ds-keystore-secret-key";
046    // Attribute types.
047    static final String ATTR_ALIAS = "ds-keystore-alias";
048    static final String ATTR_KEY_ALGORITHM = "ds-keystore-key-algorithm";
049    static final String ATTR_KEY = "ds-keystore-key";
050    static final String ATTR_CERTIFICATE_CHAIN = "ds-keystore-certificate-chain";
051    private static final String ATTR_CERTIFICATE = "ds-keystore-certificate";
052    static final String ATTR_CERTIFICATE_BINARY = ATTR_CERTIFICATE + ";binary";
053    // Standard attribute types.
054    static final String ATTR_OBJECT_CLASS = "objectClass";
055    static final String ATTR_MODIFY_TIME_STAMP = "modifyTimeStamp";
056    static final String ATTR_CREATE_TIME_STAMP = "createTimeStamp";
057
058    static {
059        try (final InputStream inputStream = SCHEMA_LDIF_URL.openStream();
060             final LDIFEntryReader reader = new LDIFEntryReader(inputStream)) {
061            SCHEMA = new SchemaBuilder(getCoreSchema())
062                    .addSchema(reader.readEntry(), false)
063                    .toSchema()
064                    .asNonStrictSchema();
065        } catch (final IOException e) {
066            throw new RuntimeException(e);
067        }
068
069        OBJECT_CLASSES = unmodifiableSet(new LinkedHashSet<>(asList(SCHEMA.getObjectClass(OC_KEY_STORE_OBJECT),
070                                                                    SCHEMA.getObjectClass(OC_TRUSTED_CERTIFICATE),
071                                                                    SCHEMA.getObjectClass(OC_SECRET_KEY),
072                                                                    SCHEMA.getObjectClass(OC_PRIVATE_KEY))));
073
074        ATTRIBUTE_TYPES = unmodifiableSet(new LinkedHashSet<>(asList(SCHEMA.getAttributeType(ATTR_ALIAS),
075                                                                     SCHEMA.getAttributeType(ATTR_KEY_ALGORITHM),
076                                                                     SCHEMA.getAttributeType(ATTR_KEY),
077                                                                     SCHEMA.getAttributeType(ATTR_CERTIFICATE_CHAIN),
078                                                                     SCHEMA.getAttributeType(ATTR_CERTIFICATE))));
079    }
080
081    /**
082     * Returns the set of LDAP object classes required in order to support the OpenDJ security provider.
083     *
084     * @return The set of LDAP object classes required in order to support the OpenDJ security provider.
085     */
086    public static Set<ObjectClass> getObjectClasses() {
087        return OBJECT_CLASSES;
088    }
089
090    /**
091     * Returns the set of LDAP attribute types required in order to support the OpenDJ security provider.
092     *
093     * @return The set of LDAP attribute types required in order to support the OpenDJ security provider.
094     */
095    public static Set<AttributeType> getAttributeTypes() {
096        return ATTRIBUTE_TYPES;
097    }
098
099    /**
100     * Returns a URL referencing a resource containing the LDIF schema that is required in order to support the
101     * OpenDJ security provider.
102     *
103     * @return The URL referencing the LDIF schema.
104     */
105    public static URL getSchemaLDIFResource() {
106        return SCHEMA_LDIF_URL;
107    }
108
109    /**
110     * Adds the schema elements required by the OpenDJ security provider to the provided schema builder.
111     *
112     * @param builder
113     *         The schema builder to which the schema elements should be added.
114     * @return The schema builder.
115     */
116    public static SchemaBuilder addOpenDJProviderSchema(final SchemaBuilder builder) {
117        for (final AttributeType attributeType : ATTRIBUTE_TYPES) {
118            builder.buildAttributeType(attributeType).addToSchema();
119        }
120        for (final ObjectClass objectClass : OBJECT_CLASSES) {
121            builder.buildObjectClass(objectClass).addToSchema();
122        }
123        return builder;
124    }
125
126    private OpenDJProviderSchema() {
127        // Prevent instantiation.
128    }
129}