Issue 4190: In IDL in Section 2 the raises clause has been left out
Issue 4191: use of "any"
Issue 4192: Replace the term "local value object type" as used in 2.2
Issue 4193: The PKIStatus constants are not explained sufficiently.
Issue 4194: In section 2.3.5.2 a transaction_ID is introduced without sufficient explan
Issue 4195: Insufficient semantic detail
Issue 4196: The exceptions listed in Appendix A are not described in section 2.
Issue 4197: issues in the PKI spec need to be brought into line with AMI.
Issue 4205: Specification of EncodingType
Issue 4206: Specification of CertificateType
Issue 4207: Naming of RepresentationType
Issue 4443: PKI - RepositoryProviderInfo defintion
Issue 4444: PKI Repository issue
Issue 4477: PKI RegistrationAuthority QUERY
Issue 4479: PKI AuthorityInfoType - missing documentation
Issue 4480: PKIAuthority module - definition of RequestManager
Issue 4481: AuthorityProviderInfo - supplementary info desirable
Issue 4190: In IDL in Section 2 the raises clause has been left out (pki-ftf)
Click here for this issue's archive.
Source: DSTC (Mr. Simon Gibson, gibson(at)dstc.edu.au)
Nature: Uncategorized Issue
Severity:
Summary:
In IDL in Section 2 the raises clause has been left out. This is in contrast to the IDL in the appendix and is confusing.
The use of "any" rather than a union to handle the representation_type in structures for Certificates, CRLs etc. Sections 2.2.3-7
Change structs to valuetypes to the following:
From
struct Certificate {
CertificateType certificate_type;
any representation_type;
};
To
valuetype Certificate {
private CertificateType certificate_type;
private EncodedData data;
};
-------------------------------------------------------
From
struct CRL {
CRLType crl_type;
any representation_type;
};
To
valuetype CRL {
private CRLType crl_type;
private EncodedData data;
};
-------------------------------------------------------
From
struct CertificateRequest {
CertificateRequestType cert_request_type;
any representation_type;
};
To
valuetype CertificateRequest {
private CertificateRequestType cert_request_type;
private EncodedData data;
};
-------------------------------------------------------
From
struct Continue {
ContinueType continue_type;
any representation_type;
};
To
valuetype Continue {
private ContinueType continue_type;
private EncodedData data;
};
-------------------------------------------------------
From
struct CertRevocation {
CertRevocationType cert_rev_type;
any representation_type;
};
To
valuetype CertRevocation {
private CertRevocationType cert_rev_type;
private EncodedData data;
};
-------------------------------------------------------
From
struct KeyRecResponse {
KeyRecoveryType key_recovery;
any representation_type;
};
To
valuetype KeyRecResponse {
private KeyRecoveryType key_recovery;
private EncodedData data;
};
-------------------------------------------------------
struct CertificateStatusRequest {
CertificateStatusRequestType type;
any representation_type;
};
To
valuetype CertificateStatusRequest {
private CertificateStatusRequestType type;
private EncodedData data;
};
-------------------------------------------------------
From
struct CertificateStatusResponse {
CertificateStatusResponseType type;
any representation_type;
};
To
valuetype CertificateStatusResponse {
private CertificateStatusResponseType type;
private EncodedData data;
};
The term "local value object type" used in 2.2 should probably be replaced by "value type". Sections 2.2.3-7
The PKIStatus constants are not explained sufficiently.
In section 2.3.5.2 a transaction_ID is introduced without sufficient explanation.
Add text as follows: A read only attribute representing an identifier for a particular transaction. This attribute relates directly to existing PKI entities. Currently a transaction will be given some unique identifier that relates to a particular transaction with an authority. In the case of using CORBA the unique identifier is not directly required due to the use of a RequestManager object for each transaction. This attribute is supplied so that the identifier provided by the back end authority can be obtained by a CORBA client
Insufficient semantic detail to cover the lifetime of Request<sometype>Manager objects ie when can the server clean up resources.
The exceptions listed in Appendix A are not described in section 2.
The detail to which the specification deals with issues regarding asynchronous messaging. The specification deals directly with concepts concerned with Asynchronous Message Invocation (AMI) and issues in the PKI spec need to be brought into line with AMI.
Simply, the changes proposed simplify the interfaces in PKIAuthority by removing anything related to callbacks and polling not using AMI. This simplifies the specification dramatically. Specifically changes proposed are: 1) IDL Changes a) Remove interface RegistrationAuthority_CB b) Remove interface CertificateAuthority_CB c) Remove interface CertificateCallback d) Remove interface RevocationCallback e) Remove interface KeyUpdateCallback f) Remove interface KeyRecoveryCallback 2) Text Changes a) Remove section 2.3.2 RegistrationAuthority_CB b) Remove section 2.3.4 CertificateAuthority_CB c) Remove section 2.3.10 CertificateCallback d) Remove section 2.3.11 RevocationCallback e) Remove section 2.3.12 KeyUpdateCallback f) Remove section 2.3.13 KeyRecoveryCallback g) Modify Paragraph 2 in section 1.4 removing references to callback or polling to: "In addressing the interactive nature of PKI messaging additional interfaces have been added. These are the RequestManager interfaces. A RequestManager object is created by the authority. This is then used for any subsequent operations and status enquiries for a particular request. Asynchronous behaviorcan be addressed by using Asynchronous Method Invocation (AMI) described in CORBA Messaging." h) Modify Figure 1-2 removing Callback object and associated text. i) Remove the term Polling is section 1.4.3 to "Certificate Request". j) Remove section 1.4.4 Certificate Request Using a Callback k) Modify text in section 1.6.2 to: "A significant design decision for this specification was in addressing the potential for asynchronous behavior combined with the potential for a level of interactivity between client and target entities. Each certification domain will have its own policy with which to manage certificate functionality. Depending on this policy it is possible for significant delays to occur between an initial request and a returned result due to the possible need for an out of band exchange. For example, a CA may require that a phone call or some interaction via email is made as part of the authentication process adding a significant delay. A synchronous invocation may block during this delay. This can be handled using an AMI aware ORB or simply ignored and wait for the invocation to be returned. The potential for interactivity between an authority (CA or RA) and a client is also possible. An example of this interactivity might be where a certificate request has been made using a public key, the authority requires assurance that the client is in possession of the associated private key and policy dictates the use of a challenge response. This will require an extra exchange of messages and that the client may also be directly involved (by needing to supply a passphrase to unlock the private key). This interactivity for a request is addressed using the RequestManager interfaces. When a request is initiated a RequestManager object reference is returned, and this is used to perform further interaction, status checking, or to return results for that particular request. The interaction of client and authority entities in a PKI domain is typically a combination of both an interactive dialogue, with state being maintained on the server side, combined with asynchronous messaging behavior. The RequestManager interface is created by the authority and encapsulates everything that relates to this a particular request. The client entity receives a reference to a interface after an initial request and continues to use it for as long as the request is outstanding. Resources related to RequestManagers can be reclaimed by the CertificateAuthority or RegistrationAuthority after either a status of either PKISuccess, PKISuccessWithWarning or PKIFailed. For a status of PKISuccessAfterConfirm the resources can be reclaimed after the confirm_content() operation has been invoked."
Section 2 "PKI Interface" does not define EncodingType. There is a an introduction to this is section 1, and details in the IDL, however, for completeness - EncodingType should be declared under section 2, probably following the definition of Opaque.
Add the following text to Chapter 2 after Chapter 2.2.2 Opaque "2.2.X EncodingType The EncodingType describes the way in which the byte representation is encoded. This is used to explicitly name the encoding method used. Some examples are ASN.1 Distinguished Encoding Rules (DER), ASN.1 Basic Encoding Rules (BER) ar perhaps Base 64 encoding."
Section 2 "PKI Interface" does not define CertificateType. For completeness CertificateType should be declared under section 2, probably following the definition of EncodingType (see issue B).
Add the following text to Chapter 2 after Chapter 2.2.2 Opaque "2.2.X CertificateType The CertificateType is used to explicitly describe the type of certificate that has been encoded. Some examples of certificate types are the X509 versions of certificate (version 3 being the most common in use), Pretty Good Privacy (PGP) certificates or Simple Public Key Infrastructure (SPKI) certificates."
The name "RepresentationType" would indicate that the type is a definition of a particular representation type, when in fact is a structure carrying a particular set of encoded information. For clarity this type should be renaming to something like "EncodedInformation".
Simple name change (PKI.idl). From
struct RepresentationType {
EncodingType encoding_type;
Opaque date;
};
To
struct EncodedData {
EncodingType encoding_type;
Opaque data;
};
The current spec defines RepositoryProviderInfo as an struct.
Given that it has approximately 14 state members, I suggest we
redefine it as a valuetype simply on the grounds that it is more
easily modifiable in the future (using a valuetype will maintain
backward compatibility because we can extend it if needed). It
also means that implementations could provide supplementary
information without breaking interfaces or interoperability.
This is the current definition:
struct RepositoryProviderInfo {
string standardDescription;
string standardVersion;
string productDescription;
string productVersion;
string productVendor;
PKI::CertificateInfoList supportedCertificates;
PKI::CRLInfoList supportedCRLs;
PKI::CertificateInfoList supportedCrossCertificates;
string user_attribute_name;
string ca_attribute_name;
string crl_attribute_name;
string certificatePair_attribute_name;
string deltaCRL_attribute_name;
string arl_attribute_name;
};
I propose we change this to:
valuetype RepositoryProviderInfo
{
public string standardDescription;
public string standardVersion;
public string productDescription;
public string productVersion;
public string productVendor;
public PKI::CertificateInfoList supportedCertificates;
public PKI::CRLInfoList supportedCRLs;
public PKI::CertificateInfoList supportedCrossCertificates;
public string user_attribute_name;
public string ca_attribute_name;
public string crl_attribute_name;
public string certificatePair_attribute_name;
public string deltaCRL_attribute_name;
public string arl_attribute_name;
};
The same case may apply for some of the other info types - but for the
moment I'm focussing on the repository interfaces - more question later!
The current spec defines RepositoryProviderInfo as an
struct. Given that it has approximately 14 state members, I suggest we
redefine it as a valuetype simply on the grounds that it is more
easily modifiable in the future (using a valuetype will maintain
backward compatibility because we can extend it if needed). It also
means that implementations could provide supplementary information
without breaking interfaces or interoperability. This is the current
definition:
struct RepositoryProviderInfo {
string standardDescription;
string standardVersion;
string productDescription;
string productVersion;
string productVendor;
PKI::CertificateInfoList supportedCertificates;
PKI::CRLInfoList supportedCRLs;
PKI::CertificateInfoList supportedCrossCertificates;
string user_attribute_name;
string ca_attribute_name;
string crl_attribute_name;
string certificatePair_attribute_name;
string deltaCRL_attribute_name;
string arl_attribute_name;
};
Proposed change of struct to 2 separate valuetypes. As follows:
valuetype RepositoryProviderInfo {
public string standardDescription;
public string standardVersion;
public string productDescription;
public string productVersion;
public string productVendor;
public PKI::CertificateInfoList supportedCertificates;
public PKI::CRLInfoList supportedCRLs;
public PKI::CertificateInfoList supportedCrossCertificates;
};
and the following with X500 type state members that may be used in the
LDAP specific repository. The new module will be making a change adding an
extension for an LDAP specific set of interfaces (the original defined
interfaces) and a simpler Repository interface to be used instead. This
will be described in detail in another issue ie 4444
module PKIExtension {
valuetype RepositoryMappingInfo {
public string user_attribute_name;
public string ca_attribute_name;
public string crl_attribute_name;
public string certificatePair_attribute_name;
public string deltaCRL_attribute_name;
public string arl_attribute_name;
};
};
After going through the PKI Repository module in more detail I'm running into a number of problems concerning implied implementation approach that is forced on the developer (effectively the implied implementation is an LDAP directory). It seems that the Repository is defined with the assumption that (a) storage slot attribute names are passed as parameters and (b) the storage values for attributes are always an any. This complicates the implementation approach if you have alternative "more structured" storage systems available (e.g. PSS - for example, using PSS I can store CORBA values and object references directly with complete type safety and practically zero additional code. This "implementation constraint" is a supposedly "implementation independent" spec is a significant issue.
Simplify implementation for the Repository by creating a simplified
interface that is friendly to other possible implementations such as
the Persistent State Storage. However it is important to keep the
LDAP-centric current definition to still handle the case where LDAP is
used providing operations for dealing with finer grained details.
In essence propose we have 2 modules one for a new simpler interface
and ane for the current repository IDL.
module PKIRepository {
// contain simplified interfaces and valuetypes
};
module PKIExtension {
// current repository stuff
};
In detail:
-----------------------
// PKIRepository.idl
#ifndef __PKIREPOSITORY_IDL
#define __PKIREPOSITORY_IDL
#include <PKI.idl>
#pragma prefix "omg.org"
module PKIRepository {
valuetype RepositoryProviderInfo {
public string standardDescription;
public string standardVersion;
public string productDescription;
public string productVersion;
public string productVendor;
public PKI::CertificateInfoList supportedCertificates;
public PKI::CRLInfoList supportedCRLs;
public PKI::CertificateInfoList supportedCrossCertificates;
};
exception UnknownPrincipal {
string name;
};
exception RepositoryError {
string name;
};
exception DuplicatePrincipal {
string name;
};
valuetype PKIPrincipalValue {
private string name;
private PKI::CertificateList certificates;
private PKI::CertificatePairList;
private PKI::CRL crl;
private PKI::CRL delta;
private PKI::CRL arl;
};
interface Repository {
readonly attribute RepositoryProviderInfo info;
void publish( in PrincipalValue principal )
raises ( DuplicatePrincipal, RepositoryError );
PKIPrincipalValue locate ( in string name )
raises ( UnknownPrincipal, RepositoryError );
void delete ( in string name )
raises ( UnknownPrincipal, RepositoryError );
void update ( in PrincipalValue principal )
raises ( UnknownPrincipal, RepositoryError);
};
};
#endif
------------------------
// PKIExtension.idl
#include<PKI.idl>
#include<PKIRepository.idl>
module PKIExtension {
// current repository stuff
valuetype RepositoryMappingInfo {
public string user_attribute_name;
public string ca_attribute_name;
public string crl_attribute_name;
public string certificatePair_attribute_name;
public string deltaCRL_attribute_name;
public string arl_attribute_name;
};
typedef string PKIName;
typedef sequence <PKIName> PKINameList;
struct PKIAttribute {
string name;
any value;
};
typedef sequence <PKIAttribute> PKIAttributeList;
struct PKIPrincipal {
PKIName name;
PKIAttributeList attributes;
};
struct Schema {
PKIAttributeList attribute_defs;
PKIAttributeList syntax_defs;
};
enum PrincipalAttributeErrorReason {
MissingPKIAttributes,
InvalidPKIAttributes
};
exception PrincipalAttributeError {
PrincipalAttributeErrorReason reason;
PKIPrincipal principal;
PKINameList attribute_names;
};
// rename to LDAPRepository
interface LDAPRepository : PKIRepository::Repository {
// New method
RepositoryMappingInfo mapping();
Schema get_schema();
void publish_certificate(
in PKIPrincipal principal,
in PKI::Certificate certificate, in string attr_name)
raises (PKIRepository::UnknownPrincipal,
PrincipalAttributeError,
PKIRepository::RepositoryError);
PKI::CertificateList get_certificate(
in PKIPrincipal principal, in string attr_name)
raises (PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void delete_certificate(
in PKIPrincipal principal,
in PKI::Certificate certificate, in string attr_name)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void publish_crl(in PKIPrincipal principal, in PKI::CRL crl,
in string attr_name)
raises(PKIRepository::UnknownPrincipal,
PrincipalAttributeError,
PKIRepository::RepositoryError);
PKI::CRL get_crl(in PKIPrincipal principal, in string attr_name)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void delete_crl(in PKIPrincipal principal,
in PKI::CRL crl,in string attr_name)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void publish_certificate_pair(
in PKIPrincipal principal, in PKI::CertificatePair certPair,
in string attr_name)
raises(PKIRepository::UnknownPrincipal,
PrincipalAttributeError,
PKIRepository::RepositoryError);
PKI::CertificatePairList get_certificate_pair(
in PKIPrincipal principal, in string attr_name)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void delete_certificate_pair(
in PKIPrincipal principal,
in PKI::CertificatePair certificate_pair,
in string attr_name)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void publish_user_certificate(in PKIPrincipal principal,
in PKI::Certificate certificate)
raises(PKIRepository::UnknownPrincipal,
PrincipalAttributeError,
PKIRepository::RepositoryError);
PKI::CertificateList get_user_certificate(in PKIPrincipal principal)
raises(UnknownPrincipal,RepositoryError);
void delete_user_certificate(in PKIPrincipal principal,
in PKI::Certificate certificate)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void publish_ca_certificate(
in PKIPrincipal principal,
in PKI::Certificate certificate)
raises(PKIRepository::UnknownPrincipal,
PrincipalAttributeError,
PKIRepository::RepositoryError);
PKI::CertificateList get_ca_certificate(in PKIPrincipal principal)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void delete_ca_certificate(in PKIPrincipal principal,
in PKI::Certificate certificate)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void publish_default_crl(in PKIPrincipal principal, in PKI::CRL crl)
raises(PKIRepository::UnknownPrincipal,
PrincipalAttributeError,
PKIRepository::RepositoryError);
PKI::CRL get_default_crl(in PKIPrincipal principal)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void delete_default_crl(in PKIPrincipal principal, in PKI::CRL crl)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void publish_default_certificate_pair(in PKIPrincipal principal,
in PKI::CertificatePair certificate_pair)
raises(PKIRepository::UnknownPrincipal,
PrincipalAttributeError,
PKIRepository::RepositoryError);
PKI::CertificatePairList get_default_certificate_pair(
in PKIPrincipal principal)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void delete_default_certificate_pair(in PKIPrincipal principal,
in PKI::CertificatePair certificate_pair)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void publish_delta_crl(in PKIPrincipal principal,
in PKI::CRL delta_crl)
raises(PKIRepository::UnknownPrincipal, PrincipalAttributeError,
PKIRepository::RepositoryError);
PKI::CRL get_delta_crl(in PKIPrincipal principal)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void delete_delta_crl(in PKIPrincipal principal, in PKI::CRL delta_crl)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void publish_arl(in PKIPrincipal principal, in PKI::CRL arl)
raises(PKIRepository::UnknownPrincipal,
PrincipalAttributeError,
PKIRepository::RepositoryError);
PKI::CRL get_arl(in PKIPrincipal principal)
raises(PKIRepository::UnknownPrincipal,
PKIRepository::RepositoryError);
void delete_arl(in PKIPrincipal principal, in PKI::CRL arl)
raises(PKIRepository::UnknownPrincipal,
RPKIRepository::epositoryError);
};
};
The specification of the get_authority_info operation on the
RegistrationAuthority
interface does seem to has sufficient information describing the expected
semantics.
I have included the extract of the javadoc description that I have put
together based
on the spec, however, this isn't a sufficient description to implement
against.
Secondly, the method and argument names don't seem to be symmetric with the
intent of
the operation. As far as I understand, the operation "get_authority_info"
actually
serves as a post-message-get-reply operation, and the arguments
"AuthorityInfo" are
actually the messages in and out. If that's correct, then both operation
and
argument types should be renamed to imply this.
Any clarification on this would be appreciated.
/**
* Message exchange between a client entity and authority. For example
* this may provide a method for a client to determine the authentication
* policy of the authority.
*
* @param in_authority_info The encoded message input to authority.
* @param out_authority_info The encoded returned message from
* authority.
* @return Status value.
* @exception UnsupportedTypeException
* @exception UnsupportedEncodingException
* @exception MalformedDataException
*/
public int get_authority_info(AuthorityInfo in_authority_info,
AuthorityInfoHolder out_authority_info)
throws UnsupportedTypeException, UnsupportedEncodingException,
MalformedDataException
{
return 0;
}Propose that we change the IDL parameter names to "authority_info_req"
and "authority_info_resp" making the intention clearer:
public int get_authority_info(AuthorityInfo authority_info_req,
AuthorityInfoHolder authority_info_resp)
throws UnsupportedTypeException,
UnsupportedEncodingException, MalformedDataException
{ return 0; }
The following structure and contantns are declared in the PKI IDL but are not defined within the PKI specification: typedef unsigned long AuthorityInfoType; const AuthorityInfoType UnkownMessage = 0; const AuthorityInfoType PKIXCMPGeneralMessage = 1; const AuthorityInfoType CustomMessage = 0x8000;
Add the following text to Chapter 2 "2.2.X AuthorityInfoType The AuthorityInfoType is used to describe the type of a message that is being sent/received by an authority. An example type for this is a PKIX Certificate Management Protocol (CMP) general message format
Under the PKIAuthority module there is an interface call
RegistrationAuthority. This interface basically provides operations through
which the client gets a reference to a object derived from RequestManager.
For all practical purposes the RequestManager is an abstract type, whereas
the derived managers (certificate request manager, key revocation manager,
key recovery manager, key update manager) are concrete. As such, the
definition of RequestManager should be changed from a concrete to an
abstract interface.
/**
* Generic interface for a manager object.
*/
abstract interface RequestManager
{
.....
};
The AuthorityProviderInfo contains a set of information about the a
provider.
It is desirable that this be extended to include the public key of
the provider and URLs to provider specific information.
valuetype AuthorityProviderInfo
{
public string standardVersion;
public string standardDescription;
public string productVersion;
public string productDescription;
public string productVendor;
public PKI::CertificateInfoList supportedCertificates;
public PKI::CRLInfoList supportedCRLs;
public PKI::CertificateRequestInfoList supportedCertRequestTypes;
public PKI::CertificateRevocationInfoList
supportedCertRevocationTypes;
public PKI::KeyRecoveryInfoList supportedKeyRecoveryTypes;
// proposed addition
public PKI::Certificate publicKey;
public string providerHomeURL;
public string providerPublicKeyURL;
};
These additions enable a consistent mechanism to (a) access a CA or RA
public
key, (b) provide a hint to an out-of-band mechanisms through which public
key
verification can be enacted, and (c) provide access to provider information
such as published certification policy, etc.
If there are not objections - I'll raise this as an FTF issue.Current struct
struct AuthorityProviderInfo {
string standard_version;
string standard_description;
string product_version;
string product_description;
string product_vendor;
PKI::CertificateInfoList supported_certificates;
PKI::CRLInfoList supported_crls;
PKI::CertificateRequestInfoList supported_cert_request_types;
PKI::CertificateRevocationInfo supported_cert_revocation_types;
PKI::KeyRecoveryInfoList supported_key_recovery_types;
};
Be changed to the following in IDL section A.2 PKIAuthority. In essence
change to valuetype and add 3 new members (ie last 3):
valuetype AuthorityProviderInfo {
public string standardVersion;
public string standardDescription;
public string productVersion;
public string productDescription;
public string productVendor;
public PKI::CertificateInfoList supportedCertificates;
public PKI::CRLInfoList supportedCRLs;
public PKI::CertificateRequestInfoList supportedCertRequestTypes;
public PKI::CertificateRevocationInfoList supportedCertRevocationTypes;
public PKI::KeyRecoveryInfoList supportedKeyRecoveryTypes;
// proposed addition
public PKI::Certificate publicKey;
public string providerHomeURL;
public string providerPublicKeyURL;
};