标签: CMP

  • CMP(Certificate Management Protocol)

    CMP(Certificate Management Protocol)

    CMP是由IETF开发的协议,用于证书管理,包括证书申请、更新、撤销等。CMP协议的标准由IETF的RFC 4210定义。CMP协议消息的格式基于ASN.1(Abstract Syntax Notation One)描述,并使用DER(Distinguished Encoding Rules)进行编码。
    RFC4210定义的是CMP V2,最新的CMP V3(RFC9480)也已经发布了。

    以下是关于CMP协议格式的详细说明

    1. CMP协议消息的基本结构

    CMP协议消息的基本结构由以下几个部分组成:

    1.1. PKIMessage

    PKIMessage是CMP协议的基本消息类型,包含了所有CMP消息的通用结构。其ASN.1描述如下:

    “`asn.1
    PKIMessage ::= SEQUENCE {
    header PKIHeader,
    body PKIBody,
    protection [0] PKIProtection OPTIONAL,
    extraCerts [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate OPTIONAL
    }

    <pre><code class="line-numbers">- **header**:PKIHeader,包含消息的元数据,如消息类型、发送者和接收者信息等。
    – **body**:PKIBody,包含实际的消息内容,如证书请求、证书响应等。
    – **protection**:PKIProtection,可选字段,用于保护消息的完整性和真实性。
    – **extraCerts**:SEQUENCE OF CMPCertificate,可选字段,包含额外的证书。

    ### 1.2. PKIHeader

    PKIHeader包含消息的元数据,其ASN.1描述如下:

    “`asn.1
    PKIHeader ::= SEQUENCE {
    pvno INTEGER { cmp1999(1), cmp2000(2) },
    sender GeneralName,
    recipient GeneralName,
    messageTime [0] GeneralizedTime OPTIONAL,
    protectionAlg [1] AlgorithmIdentifier OPTIONAL,
    senderKID [2] KeyIdentifier OPTIONAL,
    recipKID [3] KeyIdentifier OPTIONAL,
    transactionID [4] OCTET STRING OPTIONAL,
    senderNonce [5] OCTET STRING OPTIONAL,
    recipNonce [6] OCTET STRING OPTIONAL,
    freeText [7] PKIFreeText OPTIONAL,
    generalInfo [8] SEQUENCE SIZE (1..MAX) OF InfoTypeAndValue OPTIONAL
    }

    • pvno:协议版本号。
    • sender:发送者的标识。
    • recipient:接收者的标识。
    • messageTime:消息的时间戳(可选)。
    • protectionAlg:用于保护消息的算法标识符(可选)。
    • senderKID:发送者的密钥标识符(可选)。
    • recipKID:接收者的密钥标识符(可选)。
    • transactionID:事务ID(可选)。
    • senderNonce:发送者的随机数(可选)。
    • recipNonce:接收者的随机数(可选)。
    • freeText:自由文本(可选)。
    • generalInfo:一般信息(可选)。

    1.3. PKIBody

    PKIBody包含实际的消息内容,其ASN.1描述如下:

    “`asn.1
    PKIBody ::= CHOICE {
    ir [0] CertReqMessages, — Initialization Request
    ip [1] CertRepMessage, — Initialization Response
    cr [2] CertReqMessages, — Certification Request
    cp [3] CertRepMessage, — Certification Response
    p10cr [4] CertificationRequest, — PKCS #10 Certificate Request
    popdecc [5] POPODecKeyChallContent, — Proof-of-Possession Challenge
    popdecr [6] POPODecKeyRespContent, — Proof-of-Possession Response
    kur [7] CertReqMessages, — Key Update Request
    kup [8] CertRepMessage, — Key Update Response
    krr [9] CertReqMessages, — Key Recovery Request
    krp [10] KeyRecRepContent, — Key Recovery Response
    rr [11] RevReqContent, — Revocation Request
    rp [12] RevRepContent, — Revocation Response
    ccr [13] CertReqMessages, — Cross-Certification Request
    ccp [14] CertRepMessage, — Cross-Certification Response
    ckuann [15] CAKeyUpdAnnContent, — CA Key Update Announcement
    cann [16] CertAnnContent, — Certificate Announcement
    rann [17] RevAnnContent, — Revocation Announcement
    crlann [18] CRLAnnContent, — CRL Announcement
    pkiconf [19] PKIConfirmContent, — Confirmation
    nested [20] NestedMessageContent, — Nested Message
    genm [21] GenMsgContent, — General Message
    genp [22] GenRepContent, — General Response
    error [23] ErrorMsgContent, — Error Message
    certConf [24] CertConfirmContent, — Certificate Confirmation
    pollReq [25] PollReqContent, — Polling Request
    pollRep [26] PollRepContent — Polling Response
    }

    <pre><code class="line-numbers">- **ir**:初始化请求(Initialization Request)。
    – **ip**:初始化响应(Initialization Response)。
    – **cr**:认证请求(Certification Request)。
    – **cp**:认证响应(Certification Response)。
    – **p10cr**:PKCS #10证书请求(PKCS #10 Certificate Request)。
    – **popdecc**:证明密钥拥有权挑战(Proof-of-Possession Challenge)。
    – **popdecr**:证明密钥拥有权响应(Proof-of-Possession Response)。
    – **kur**:密钥更新请求(Key Update Request)。
    – **kup**:密钥更新响应(Key Update Response)。
    – **krr**:密钥恢复请求(Key Recovery Request)。
    – **krp**:密钥恢复响应(Key Recovery Response)。
    – **rr**:撤销请求(Revocation Request)。
    – **rp**:撤销响应(Revocation Response)。
    – **ccr**:交叉认证请求(Cross-Certification Request)。
    – **ccp**:交叉认证响应(Cross-Certification Response)。
    – **ckuann**:CA密钥更新公告(CA Key Update Announcement)。
    – **cann**:证书公告(Certificate Announcement)。
    – **rann**:撤销公告(Revocation Announcement)。
    – **crlann**:CRL公告(CRL Announcement)。
    – **pkiconf**:确认(Confirmation)。
    – **nested**:嵌套消息(Nested Message)。
    – **genm**:一般消息(General Message)。
    – **genp**:一般响应(General Response)。
    – **error**:错误消息(Error Message)。
    – **certConf**:证书确认(Certificate Confirmation)。
    – **pollReq**:轮询请求(Polling Request)。
    – **pollRep**:轮询响应(Polling Response)。

    ## 2. CMP协议消息的保护

    CMP协议消息可以通过PKIProtection字段进行保护,确保消息的完整性和真实性。PKIProtection字段的ASN.1描述如下:

    “`asn.1
    PKIProtection ::= BIT STRING

    • PKIProtection:包含消息的保护信息,通常是消息的签名或MAC(消息认证码)。

    3. CMP协议消息的编码

    CMP协议消息使用ASN.1描述,并通过DER(Distinguished Encoding Rules)进行编码。DER是一种二进制编码规则,确保消息的唯一编码。

    4. 示例:CMP协议消息

    以下是一个简单的CMP协议消息示例,展示了初始化请求(Initialization Request)的结构:

    “`asn.1
    PKIMessage ::= SEQUENCE {
    header PKIHeader {
    pvno cmp2000,
    sender GeneralName { directoryName { rdnSequence { commonName "Client" } } },
    recipient GeneralName { directoryName { rdnSequence { commonName "CA" } } },
    messageTime GeneralizedTime "20230101000000Z",
    senderNonce OCTET STRING "1234567890abcdef",
    transactionID OCTET STRING "abcdef1234567890"
    },
    body PKIBody {
    ir CertReqMessages {
    CertReqMsg {
    certReq CertRequest {
    certReqId INTEGER 1,
    certTemplate CertTemplate {
    version Version v3,
    subject Name { rdnSequence { commonName "Client" } },
    publicKey SubjectPublicKeyInfo { algorithm { algorithm rsaEncryption }, subjectPublicKey BIT STRING "…" }
    }
    },
    popo ProofOfPossession { raVerified },
    regInfo SEQUENCE { }
    }
    }
    },
    protection PKIProtection "…"
    }

    <pre><code class="line-numbers">## PKI管理模型

    ### PKI实体

    – 最终实体(End Entities,EE)

    最终实体就是subject字段所代表的主体。后面最终实体都用EE表示。

    – 证书颁发机构(Certification Authority,CA)

    CA是issuer字段所代表的主体,CA可以是第三方主体,也可以是与EE相同的主体,可以是离线的也可以是在线的。root CA是EE需要直接信任的CA。

    – 注册机构(Registration Authority,RA)

    许多环境需要独立于CA的注册机构。
    注册机构可能执行的功能因情况而异,但可能包括个人身份验证、令牌分发、撤销报告、名称分配、密钥生成、密钥对存档等。
    RA是可选的,当没有RA时CA完成RA的所有功能。

    RA本身也是一个EE,RA其实就是具有可以签名私钥(签名CSR)的经过认证的EE,CA把哪体EE识别为RA取决于具体实现。一个RA可以属于多个CA。

    ### PKI管理操作

    管理操作的流程图
    “`ascii
    +—+ cert. publish +————+ j
    | | <——————— | End Entity | <——-
    | C | g +————+ “out-of-band”
    | e | | ^ loading
    | r | | | initial
    | t | a | | b registration/
    | | | | certification
    | / | | | key pair recovery
    | | | | key pair update
    | C | | | certificate update
    | R | PKI “USERS” V | revocation request
    | L | ——————-+-+—–+-+——+-+——————-
    | | PKI MANAGEMENT | ^ | ^
    | | ENTITIES a | | b a | | b
    | R | V | | |
    | e | g +——+ d | |
    | p | <———— | RA | <—–+ | |
    | o | cert. | | —-+ | | |
    | s | publish +——+ c | | | |
    | i | | | | |
    | t | V | V |
    | o | g +————+ i
    | r | <————————| CA |——->
    | y | h +————+ “out-of-band”
    | | cert. publish | ^ publication
    | | CRL publish | |
    +—+ | | cross-certification
    e | | f cross-certificate
    | | update
    | |
    V |
    +——+
    | CA-2 |
    +——+

    PKI管理操作包括:

    1. CA建立

      生成自签名证书或者中间CA证书,生成初始CRL,生成证书序列号文件,生成证书数据库

    2. EE初始化

      导入CA证书,获取CA的其它信息

    3. Certification(创建新证书的各种操作)

      3.1. initial registration/certification

      生成密钥对,注册或生成自己的证书请求

      3.2. key pair update

      更新密钥对并颁发新的证书

      3.3. certificate update

      证书过期时如果环境没有任何其它的变化则会refreshed证书

      3.4. CA key pair update

      与EE一样,CA密钥对也需要进行更新,但是会使用不同的机制

      3.5. cross-certification request

      一个CA向另一个CA请求交叉证书

      3.6. cross-certificate update

      同普通证书update

    4. Certificate/CRL discovery operations

      后面具体讲

    5. Recovery operations

      主要是key pair recovery,如果EE丢失了自己的私钥并且CA备份了EE的私钥的情况下可以请求CA恢复私钥

    6. Revocation operations

      证书吊销

    7. PSE operations

      PSE是啥RFC4210中也没说,我想指的应该是发布证书的时候确保提供一个安全渠道。

    Assumptions and Restrictions

    rfc4210中是叫这个标题,我也不知道啥意思

    1. Initiation of Registration/Certification

      第一条PKI消息的产生意味着触发Initiation of Registration/Certification,这可以发生在任何地方,包括EE,RA,CA。

    2. End Entity Message Origin Authentication

      EE与RA或CA通信时需要经过身份认证,也可以不认证。本规范中是通过secret value(用于生成保护字段的MAC,同时用于初始化请求的身份验证,华为的文档中叫秘密值)和reference value(就是senderKID的referenceNum,华为的文档中叫参考值)来认证的,secret value和reference value由CA生成并通过带外途径发送给EE。

    3. Location of Key Generation

      密钥生成的位置等同于PKI消息中首次出现密钥的地方,这可以是EE,RA,CA。

    4. Confirmation of Successful Certification

      CA生成证书后,可以让EE明确接收或不接受证书。

    Mandatory Schemes

    1. Centralized Scheme

      即中心化方案

      • Initiation of Registration/Certification由CA完成
      • 不需要End Entity Message Origin Authentication
      • Location of Key Generation生成在CA
      • 不需要Confirmation of Successful Certification
    2. Basic Authenticated Scheme
      • Initiation of Registration/Certification由EE完成
      • 需要End Entity Message Origin Authentication
      • Location of Key Generation生成在EE
      • 需要Confirmation of Successful Certification

    Proof-of-Possession (POP) of Private Key

    EE持有的私钥,需要向CA/RA证明自己是对应公钥的私钥持有者,这包括用自己的私钥对证书请求进行签名,向CA/RA发送私钥,使用私钥加密一个值。对于Key Agreement Keys,例如DH密钥,可以通过生成一个共享密钥来证明。
    POP证明有很多种,包括包含私钥,直接法(质询响应),间接法(公钥加密证书),后面还有更多说明。

    Root CA Key Update

    更新root CA的密钥是一个比较麻烦的事,因为需要所有EE,RA都要同步处理。
    需要执行的操作包括:

    1. 创建新的密钥对;

    2. 创建一个包含用新私钥签名的旧CA公钥的证书(the “old with new” certificate);

    3. 创建一个包含用旧私钥签名的新CA公钥的证书(the “new with old” certificate);

    4. 创建一个包含用新私钥签名的新CA公钥证书(the “new with new” certificate);

    5. 通过repository and/or 其它方式发送新证书(perhaps using a CAKeyUpdAnn message);

    6. 导出新的CA公钥,以便end entities可以通过”out-of-band”机制获取它(if required).

    然后,旧 CA 私钥将不再​​需要。但是,旧 CA 公钥仍将使用一段时间。当此 CA 的所有终端实体都已安全地获取新 CA 公钥时,旧 CA 公钥将也不再需要(除非出于non-repudiation目的)。”old with new”证书的有效期必须从旧密钥对的生成时间开始,到旧公钥的到期日结束(也就是与旧CA一致)。
    “new with old”证书的有效期必须从新密钥对的生成时间开始,到该 CA 的所有终端实体安全拥有新 CA 公钥的时间结束(最迟为旧公钥的到期日)。
    “new with new”证书的有效期必须从新密钥对的生成时间开始,并在 CA 下次更新其密钥对的时间或之前结束。

    数据结构

    总体PKI消息

    ```asn1
        PKIMessage ::= SEQUENCE {
            header           PKIHeader,
            body             PKIBody,
            protection   [0] PKIProtection OPTIONAL,
            extraCerts   [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
                            OPTIONAL
        }
        PKIMessages ::= SEQUENCE SIZE (1..MAX) OF PKIMessage
    ```
    
    protection 就是消息的签名或者完整性验证
    extraCerts 如果颁发证书的CA不是rootCA,则需要一个证书链来验证证书的有效性,所以这就是新证书的证书链(如果有的话)。在证书请求中还可以用于包含当前用于签名验证的证书。Root CA Key Update消息中则用于发布证书。所以这个字段在不同场景下用途也不一样。
    

    PKI消息头

        PKIHeader ::= SEQUENCE {
            pvno                INTEGER     { cmp1999(1), cmp2000(2) },
            sender              GeneralName,
            recipient           GeneralName,
            messageTime     [0] GeneralizedTime         OPTIONAL,
            protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
            senderKID       [2] KeyIdentifier           OPTIONAL,
            recipKID        [3] KeyIdentifier           OPTIONAL,
            transactionID   [4] OCTET STRING            OPTIONAL,
            senderNonce     [5] OCTET STRING            OPTIONAL,
            recipNonce      [6] OCTET STRING            OPTIONAL,
            freeText        [7] PKIFreeText             OPTIONAL,
            generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
                                InfoTypeAndValue     OPTIONAL
        }
        PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
    

    pvno 就是cmp协议的版本号,对于rfc4210来说始终是2
    sender 发送者的DN名称
    recipient 接收者的DN名称
    messageTime 消息发送时间
    protectionAlg protection字段的算法标识符
    senderKID,recipKID DH算法的密钥标识符,有多对密钥时才需要,在初始化请求中senderKID就是用于身份认证的referenceNum(参考值)
    transactionID 事务ID,也就是会话ID,一般由发起会话者生成,后面保持不变
    senderNonce,recipNonce 每个报文生成一个随机数(为什么不用递增序列?),用于防重放攻击
    freeText 包含人类可读信息(可以由多个),回复消息时使用与第一个Text相同的语言。
    generalInfo 向对方发送附加的机器可处理信息,这是一个generalInfo类型的数组,一共定义了以下generalInfo扩展:

    • ImplicitConfirm
      implicitConfirm OBJECT IDENTIFIER ::= {id-it 13}
      ImplicitConfirmValue ::= NULL
      

      如果存在这个generalInfo扩展则不发送证书确认

    • ConfirmWaitTime

      confirmWaitTime OBJECT IDENTIFIER ::= {id-it 14}
      ConfirmWaitTimeValue ::= GeneralizedTime
      

      证书确认的超时时间,如果超时则撤销证书并删除会话。

    PKI消息体

            PKIBody ::= CHOICE {
              ir       [0]  CertReqMessages,       --Initialization Req
              ip       [1]  CertRepMessage,        --Initialization Resp
              cr       [2]  CertReqMessages,       --Certification Req
              cp       [3]  CertRepMessage,        --Certification Resp
              p10cr    [4]  CertificationRequest,  --PKCS #10 Cert.  Req.
              popdecc  [5]  POPODecKeyChallContent --pop Challenge
              popdecr  [6]  POPODecKeyRespContent, --pop Response
              kur      [7]  CertReqMessages,       --Key Update Request
              kup      [8]  CertRepMessage,        --Key Update Response
              krr      [9]  CertReqMessages,       --Key Recovery Req
              krp      [10] KeyRecRepContent,      --Key Recovery Resp
              rr       [11] RevReqContent,         --Revocation Request
              rp       [12] RevRepContent,         --Revocation Response
              ccr      [13] CertReqMessages,       --Cross-Cert.  Request
              ccp      [14] CertRepMessage,        --Cross-Cert.  Resp
              ckuann   [15] CAKeyUpdAnnContent,    --CA Key Update Ann.
              cann     [16] CertAnnContent,        --Certificate Ann.
              rann     [17] RevAnnContent,         --Revocation Ann.
              crlann   [18] CRLAnnContent,         --CRL Announcement
              pkiconf  [19] PKIConfirmContent,     --Confirmation
              nested   [20] NestedMessageContent,  --Nested Message
              genm     [21] GenMsgContent,         --General Message
              genp     [22] GenRepContent,         --General Response
              error    [23] ErrorMsgContent,       --Error Message
              certConf [24] CertConfirmContent,    --Certificate confirm
              pollReq  [25] PollReqContent,        --Polling request
              pollRep  [26] PollRepContent         --Polling response
              }
    
    

    一共27种报文,还是比较多的。
    具体描述在下在面。

    Common Data Structures

    在说明具本的PKIBody前要先说一下通用的数据结构

    • 发送证书

    当需要包含证书内容时使用CertTemplate语法,CA/RA可能修改证书请求的内容,EE也可以选择拒绝CA签置的证书(如果内容被修改)。

    • Encrypted Values

    通常是私钥和证书(接收新证书),需要使用EncryptedValue数据结构,要求双方事先有能解密秘密数据的密钥。

    • 状态码和故障信息

    状态码

            PKIStatus ::= INTEGER {
                accepted               (0),
                grantedWithMods        (1),
                rejection              (2),
                waiting                (3),
                revocationWarning      (4),
                revocationNotification (5),
                keyUpdateWarning       (6)
            }
    

    故障

            PKIFailureInfo ::= BIT STRING {
                badAlg              (0),
                badMessageCheck     (1),
                badRequest          (2),
                badTime             (3),
                badCertId           (4),
                badDataFormat       (5),
                wrongAuthority      (6),
                incorrectData       (7),
                missingTimeStamp    (8),
                badPOP              (9),
                certRevoked         (10),
                certConfirmed       (11),
                wrongIntegrity      (12),
                badRecipientNonce   (13),
                timeNotAvailable    (14),
                unacceptedPolicy    (15),
                unacceptedExtension (16),
                addInfoNotAvailable (17),
                badSenderNonce      (18),
                badCertTemplate     (19),
                signerNotTrusted    (20),
                transactionIdInUse  (21),
                unsupportedVersion  (22),
                notAuthorized       (23),
                systemUnavail       (24),
                systemFailure       (25),
                duplicateCertReq    (26)
            }
            PKIStatusInfo ::= SEQUENCE {
                status        PKIStatus,
                statusString  PKIFreeText     OPTIONAL,
                failInfo      PKIFailureInfo  OPTIONAL
            }
    
    • 证书标识

    用于标只特定的证书,使用CertId数据结构

    • root CA
    OOBCert ::= Certificate
    # or
    OOBCertHash ::= SEQUENCE {
        hashAlg     [0] AlgorithmIdentifier     OPTIONAL,
        certId      [1] CertId                  OPTIONAL,
        hashVal         BIT STRING
    }
    

    对于Certificat要求:

    • 证书是自签名的,即可以使用SubjectPublicKeyInfo中的公钥验证签名
    • subject和issuer相同
    • 如果subject为空则要求SubjectAltName和issuerAltNames相同
    • key identifiers for subject and issuer相同

    OOBCertHash用途是通过带外方式获取root CA时对root CA进行验证。

    • Archive Options

    请求者希望PKI使用PKIArchiveOptions结构存档私钥

    • Publication Information

    请求者希望PKI通过PKIPublicationInfo结构发布证书

    • Proof-of-Possession Structures

      如果请求的是一个签名证书,私钥的所有权证明是通过POPOSigningKey结构完成的。

      参考附录 C and [CRMF] for POPOSigningKey 语法,

          POPOSigningKey ::= SEQUENCE {
              poposkInput           [0] POPOSigningKeyInput OPTIONAL,
              algorithmIdentifier   AlgorithmIdentifier,
              signature             BIT STRING
              #这个签名是用私钥对poposkInput的DER编码的签名,如果EE能用公钥验证这个签名就完成了私钥所有权证明
          }
          POPOSigningKeyInput ::= SEQUENCE {
              authInfo            CHOICE {
                  sender              [0] GeneralName,
                  publicKeyMAC        PKMACValue
              },
              publicKey           SubjectPublicKeyInfo
          }
      

      另一方面, 如果请求的是一个加密证书, 那么私钥的所有权证明可以用下面三种方法中的一个(包含私钥,直接法,间接法)

    • Inclusion of the Private Key

      在CertRequest请求的POPOPrivKey的thisMessage,或者通过PKIArchiveOptions字段包含私钥,这取决于是否需要私钥存档

      POPOPrivKey ::= CHOICE {
          thisMessage       [0] BIT STRING,
      -- **********
      -- * the type of "thisMessage" is given as BIT STRING in
      -- * [CRMF]; it should be "EncryptedValue" (in accordance
      -- * with Section 5.2.2, "Encrypted Values", of this specification).
      -- * Therefore, this document makes the behavioral clarification
      -- * of specifying that the contents of "thisMessage" MUST be encoded
      -- * as an EncryptedValue and then wrapped in a BIT STRING.  This
      -- * allows the necessary conveyance and protection of the
      -- * private key while maintaining bits-on-the-wire compatibility
      -- * with [CRMF].
      -- **********
      subsequentMessage [1] SubsequentMessage,
      dhMAC             [2] BIT STRING }
      
    • Indirect Method

      返回公钥加密的证书,只有用EE的私钥才能解密。

    • Challenge-Response Protocol(direct method)

      通过Challenge-Response Protocol证明EE私钥的POP

    • PoP选项总结

      下面列出了代表各种POP技术的选项. Using “SK” for “signing key”, “EK” for “encryption key”,and “KAK” for “key agreement key”, 总结如下:

      RAVerified;
      SKPOP;
      EKPOPThisMessage;
      KAKPOPThisMessage;
      KAKPOPThisMessageDHMAC;
      EKPOPEncryptedCert;
      KAKPOPEncryptedCert;
      EKPOPChallengeResp; and
      KAKPOPChallengeResp.
      

      考虑到这一系列选项,自然会问EE如何知道CA/RA支持什么选项/技术(即,在请求证书时可以使用哪些选项)。以下指南应该为EE实现者澄清这种情况。

      • RAVerified

        这是RA向CA请求是用的,EE不需要考虑

      • SKPOP

        如果EE有一个签名密钥对,则这是唯一可用选项

      • EKPOPThisMessage and KAKPOPThisMessage

        如果决定向CA/RA公开私钥,则只有这里的方法可以做到,根据密钥类型选择EKPOPThisMessage 还是 KAKPOPThisMessage

      • KAKPOPThisMessageDHMAC

        仅当CA有可用于此目的的DH证书,以及EE已经有此证书的副本时,EE才能使用此方法。如果这两个条件都成立,那么这种技术就得到了明确的支持。

      • EKPOPEncryptedCert, KAKPOPEncryptedCert, EKPOPChallengeResp, KAKPOPChallengeResp

        EE在请求消息中选择其中一个(在subsequentMessage字段中),具体取决于偏好和密钥对类型。EE在此处没有做POP;它只是向CA/RA指示要使用哪种方法。因此,如果CA/RA回复“badPOP”错误,则EE可以使用在后续消息中选择的其他POP方法重新请求。但是,请注意,本规范鼓励使用EncryptedCert选项,并且还指出,当涉及RA并进行POP验证时,通常会使用质询响应。间接方法需要发送的消息更少,也比较简单是EE尽可能使用这种方法,如果是向RA提交POP证明则会使用直接方法(质询响应)

    特定操作的数据结构

    一共定义了27个操作类型,怪不得CMP是最复杂的证书协议

    • Initialization Request

      一个Initialization请求包含CertReqMessages数据结构作为PKI Body,该数据结构指定要请求的证书(CRMF格式(RFC4211),类似于PKCS#10),通常会包含SubjectPublicKeyInfo、KeyId和Validity字段。此消息用于首次初始化PKI实体时。
      因为是首次请求证书需要带外方式获取身份验证信息,使用MSG_MAC_ALG进行身份验证,MAC信息是用共享的Secret加了盐的。senderKID就是参考值。
      一个请求可以包含多个证书,证书模板(要请求的证书)放在CertTemplate字段中。

      CertReqMessages在Rfc4211中定义,很复杂,以下是ASN.1代码:

      -- Core definitions for this module
      
      CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg
      
      CertReqMsg ::= SEQUENCE {
      certReq   CertRequest,
      popo       ProofOfPossession  OPTIONAL,
      -- content depends upon key type
      regInfo   SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue OPTIONAL }
      
      CertRequest ::= SEQUENCE {
      certReqId     INTEGER,          -- ID for matching request and reply
      certTemplate  CertTemplate,  -- Selected fields of cert to be issued
      controls      Controls OPTIONAL }   -- Attributes affecting issuance
      
      CertTemplate ::= SEQUENCE {
      version      [0] Version               OPTIONAL,
      serialNumber [1] INTEGER               OPTIONAL,
      signingAlg   [2] AlgorithmIdentifier   OPTIONAL,
      issuer       [3] Name                  OPTIONAL,
      validity     [4] OptionalValidity      OPTIONAL,
      subject      [5] Name                  OPTIONAL,
      publicKey    [6] SubjectPublicKeyInfo  OPTIONAL,
      issuerUID    [7] UniqueIdentifier      OPTIONAL,
      subjectUID   [8] UniqueIdentifier      OPTIONAL,
      extensions   [9] Extensions            OPTIONAL }
      
      OptionalValidity ::= SEQUENCE {
      notBefore  [0] Time OPTIONAL,
      notAfter   [1] Time OPTIONAL } -- at least one MUST be present
      
      Controls  ::= SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue
      AttributeTypeAndValue ::= SEQUENCE {
      type         OBJECT IDENTIFIER,
      value        ANY DEFINED BY type }
      
      ProofOfPossession ::= CHOICE {
      raVerified        [0] NULL,
      -- used if the RA has already verified that the requester is in
      -- possession of the private key
      signature         [1] POPOSigningKey,
      keyEncipherment   [2] POPOPrivKey,
      keyAgreement      [3] POPOPrivKey }
      
      POPOSigningKey ::= SEQUENCE {
      poposkInput           [0] POPOSigningKeyInput OPTIONAL,
      algorithmIdentifier   AlgorithmIdentifier,
      signature             BIT STRING }
      -- The signature (using "algorithmIdentifier") is on the
      -- DER-encoded value of poposkInput.  NOTE: If the CertReqMsg
      -- certReq CertTemplate contains the subject and publicKey values,
      -- then poposkInput MUST be omitted and the signature MUST be
      -- computed over the DER-encoded value of CertReqMsg certReq.  If
      -- the CertReqMsg certReq CertTemplate does not contain both the
      -- public key and subject values (i.e., if it contains only one
      -- of these, or neither), then poposkInput MUST be present and
      -- MUST be signed.
      
      
      POPOSigningKeyInput ::= SEQUENCE {
      authInfo            CHOICE {
          sender              [0] GeneralName,
          -- used only if an authenticated identity has been
          -- established for the sender (e.g., a DN from a
          -- previously-issued and currently-valid certificate)
          publicKeyMAC        PKMACValue },
          -- used if no authenticated GeneralName currently exists for
          -- the sender; publicKeyMAC contains a password-based MAC
          -- on the DER-encoded value of publicKey
      publicKey           SubjectPublicKeyInfo }  -- from CertTemplate
      
      PKMACValue ::= SEQUENCE {
      algId  AlgorithmIdentifier,
      -- algorithm value shall be PasswordBasedMac {1 2 840 113533 7 66 13}
      -- parameter value is PBMParameter
      value  BIT STRING }
      
      PBMParameter ::= SEQUENCE {
      salt                OCTET STRING,
      owf                 AlgorithmIdentifier,
      -- AlgId for a One-Way Function (SHA-1 recommended)
      iterationCount      INTEGER,
      -- number of times the OWF is applied
      mac                 AlgorithmIdentifier
      -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11],
      }   -- or HMAC [HMAC, RFC2202])
      
      POPOPrivKey ::= CHOICE {
      thisMessage       [0] BIT STRING,         -- Deprecated
      -- possession is proven in this message (which contains the private
      -- key itself (encrypted for the CA))
      subsequentMessage [1] SubsequentMessage,
      -- possession will be proven in a subsequent message
      dhMAC             [2] BIT STRING,         -- Deprecated
      agreeMAC          [3] PKMACValue,
      encryptedKey      [4] EnvelopedData }
      
      -- for keyAgreement (only), possession is proven in this message
      -- (which contains a MAC (over the DER-encoded value of the
      -- certReq parameter in CertReqMsg, which MUST include both subject
      -- and publicKey) based on a key derived from the end entity's
      -- private DH key and the CA's public DH key);
      
      SubsequentMessage ::= INTEGER {
      encrCert (0),
      -- requests that resulting certificate be encrypted for the
      -- end entity (following which, POP will be proven in a
      -- confirmation message)
      challengeResp (1) }
      -- requests that CA engage in challenge-response exchange with
      -- end entity in order to prove private key possession
      
      -- Object identifier assignments --
      
      -- Registration Controls in CRMF
      id-regCtrl OBJECT IDENTIFIER ::= { id-pkip 1 }
      
      
      id-regCtrl-regToken OBJECT IDENTIFIER ::= { id-regCtrl 1 }
      --with syntax:
      RegToken ::= UTF8String
      
      id-regCtrl-authenticator OBJECT IDENTIFIER ::= { id-regCtrl 2 }
      --with syntax:
      Authenticator ::= UTF8String
      
      id-regCtrl-pkiPublicationInfo OBJECT IDENTIFIER ::= { id-regCtrl 3 }
      --with syntax:
      
      PKIPublicationInfo ::= SEQUENCE {
      action     INTEGER {
                  dontPublish (0),
                  pleasePublish (1) },
      pubInfos  SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL }
      -- pubInfos MUST NOT be present if action is "dontPublish"
      -- (if action is "pleasePublish" and pubInfos is omitted,
      -- "dontCare" is assumed)
      
      SinglePubInfo ::= SEQUENCE {
      pubMethod    INTEGER {
          dontCare    (0),
          x500        (1),
          web         (2),
          ldap        (3) },
      pubLocation  GeneralName OPTIONAL }
      
      id-regCtrl-pkiArchiveOptions     OBJECT IDENTIFIER ::= { id-regCtrl 4 }
      --with syntax:
      PKIArchiveOptions ::= CHOICE {
      encryptedPrivKey     [0] EncryptedKey,
      -- the actual value of the private key
      keyGenParameters     [1] KeyGenParameters,
      -- parameters that allow the private key to be re-generated
      archiveRemGenPrivKey [2] BOOLEAN }
      -- set to TRUE if sender wishes receiver to archive the private
      -- key of a key pair that the receiver generates in response to
      -- this request; set to FALSE if no archival is desired.
      
      EncryptedKey ::= CHOICE {
      encryptedValue        EncryptedValue,   -- Deprecated
      envelopedData     [0] EnvelopedData }
      -- The encrypted private key MUST be placed in the envelopedData
      -- encryptedContentInfo encryptedContent OCTET STRING.
      
      EncryptedValue ::= SEQUENCE {
      intendedAlg   [0] AlgorithmIdentifier  OPTIONAL,
      -- the intended algorithm for which the value will be used
      symmAlg       [1] AlgorithmIdentifier  OPTIONAL,
      -- the symmetric algorithm used to encrypt the value
      encSymmKey    [2] BIT STRING           OPTIONAL,
      -- the (encrypted) symmetric key used to encrypt the value
      keyAlg        [3] AlgorithmIdentifier  OPTIONAL,
      -- algorithm used to encrypt the symmetric key
      valueHint     [4] OCTET STRING         OPTIONAL,
      -- a brief description or identifier of the encValue content
      -- (may be meaningful only to the sending entity, and used only
      -- if EncryptedValue might be re-examined by the sending entity
      -- in the future)
      encValue       BIT STRING }
      -- the encrypted value itself
      -- When EncryptedValue is used to carry a private key (as opposed to
      -- a certificate), implementations MUST support the encValue field
      -- containing an encrypted PrivateKeyInfo as defined in [PKCS11],
      -- section 12.11.  If encValue contains some other format/encoding
      -- for the private key, the first octet of valueHint MAY be used
      -- to indicate the format/encoding (but note that the possible values
      -- of this octet are not specified at this time).  In all cases, the
      -- intendedAlg field MUST be used to indicate at least the OID of
      -- the intended algorithm of the private key, unless this information
      -- is known a priori to both sender and receiver by some other means.
      
      KeyGenParameters ::= OCTET STRING
      
      id-regCtrl-oldCertID          OBJECT IDENTIFIER ::= { id-regCtrl 5 }
      --with syntax:
      OldCertId ::= CertId
      
      CertId ::= SEQUENCE {
      issuer           GeneralName,
      serialNumber     INTEGER }
      
      id-regCtrl-protocolEncrKey    OBJECT IDENTIFIER ::= { id-regCtrl 6 }
      --with syntax:
      ProtocolEncrKey ::= SubjectPublicKeyInfo
      
      -- Registration Info in CRMF
      id-regInfo OBJECT IDENTIFIER ::= { id-pkip 2 }
      
      id-regInfo-utf8Pairs    OBJECT IDENTIFIER ::= { id-regInfo 1 }
      --with syntax
      UTF8Pairs ::= UTF8String
      
      
      id-regInfo-certReq       OBJECT IDENTIFIER ::= { id-regInfo 2 }
      --with syntax
      CertReq ::= CertRequest
      
      -- id-ct-encKeyWithID is a new content type used for CMS objects.
      -- it contains both a private key and an identifier for key escrow
      -- agents to check against recovery requestors.
      
      id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21}
      
      EncKeyWithID ::= SEQUENCE {
      privateKey           PrivateKeyInfo,
      identifier CHOICE {
          string             UTF8String,
          generalName        GeneralName
      } OPTIONAL
      }
      
      PrivateKeyInfo ::= SEQUENCE {
      version                   INTEGER,
      privateKeyAlgorithm       AlgorithmIdentifier,
      privateKey                OCTET STRING,
      attributes                [0] IMPLICIT Attributes OPTIONAL
      }
      
      Attributes ::= SET OF Attribute
      
    • Initialization Response

      初始化请求的响应,返回请求的证书
      CertRepMessage数据结构作为PKIBody,该数据结构为每个请求的证书提供一个PKIStatusInfo字段、一个主题证书,可能还有一个私钥(通常使用会话密钥加密,会话密钥本身使用ProtocolEncrey加密。
      CertRepMessage的asn.1代码

          CertRepMessage ::= SEQUENCE {
              caPubs       [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
                              OPTIONAL,
              response         SEQUENCE OF CertResponse
          }
      
          CertResponse ::= SEQUENCE {
              certReqId           INTEGER,
              -- to match this response with corresponding request (a value
              -- of -1 is to be used if certReqId is not specified in the
              -- corresponding request)
              status              PKIStatusInfo,
              certifiedKeyPair    CertifiedKeyPair    OPTIONAL,
              rspInfo             OCTET STRING        OPTIONAL
              -- analogous to the id-regInfo-utf8Pairs string defined
              -- for regInfo in CertReqMsg [CRMF]
          }
      
          CertifiedKeyPair ::= SEQUENCE {
              certOrEncCert       CertOrEncCert,
              privateKey      [0] EncryptedValue      OPTIONAL,
              -- see [CRMF] for comment on encoding
              publicationInfo [1] PKIPublicationInfo  OPTIONAL
          }
      
          CertOrEncCert ::= CHOICE {
              certificate     [0] CMPCertificate,
              encryptedCert   [1] EncryptedValue
          }
      
          KeyRecRepContent ::= SEQUENCE {
              status                  PKIStatusInfo,
              newSigCert          [0] CMPCertificate OPTIONAL,
              caCerts             [1] SEQUENCE SIZE (1..MAX) OF
                                                  CMPCertificate OPTIONAL,
              keyPairHist         [2] SEQUENCE SIZE (1..MAX) OF
                                                  CertifiedKeyPair OPTIONAL
          }
      
          RevReqContent ::= SEQUENCE OF RevDetails
      
          RevDetails ::= SEQUENCE {
              certDetails         CertTemplate,
              -- allows requester to specify as much as they can about
              -- the cert. for which revocation is requested
              -- (e.g., for cases in which serialNumber is not available)
              crlEntryDetails     Extensions       OPTIONAL
              -- requested crlEntryExtensions
          }
      
          RevRepContent ::= SEQUENCE {
              status       SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
              -- in same order as was sent in RevReqContent
              revCerts [0] SEQUENCE SIZE (1..MAX) OF CertId
                                                  OPTIONAL,
              -- IDs for which revocation was requested
              -- (same order as status)
              crls     [1] SEQUENCE SIZE (1..MAX) OF CertificateList
                                                  OPTIONAL
              -- the resulting CRLs (there may be more than one)
          }
      
          CAKeyUpdAnnContent ::= SEQUENCE {
              oldWithNew   CMPCertificate, -- old pub signed with new priv
              newWithOld   CMPCertificate, -- new pub signed with old priv
              newWithNew   CMPCertificate  -- new pub signed with new priv
          }
      
          CertAnnContent ::= CMPCertificate
      
          RevAnnContent ::= SEQUENCE {
              status              PKIStatus,
              certId              CertId,
              willBeRevokedAt     GeneralizedTime,
              badSinceDate        GeneralizedTime,
              crlDetails          Extensions  OPTIONAL
              -- extra CRL details (e.g., crl number, reason, location, etc.)
          }
      
          CRLAnnContent ::= SEQUENCE OF CertificateList
      
          CertConfirmContent ::= SEQUENCE OF CertStatus
      
          CertStatus ::= SEQUENCE {
              certHash    OCTET STRING,
              -- the hash of the certificate, using the same hash algorithm
              -- as is used to create and verify the certificate signature
              certReqId   INTEGER,
              -- to match this confirmation with the corresponding req/rep
              statusInfo  PKIStatusInfo OPTIONAL
          }
          CMPCertificate ::= CHOICE {
          x509v3PKCert        Certificate
          }
      
    • Certification Request(证书请求)

      现有PKI EE获得其它证书(用已有证书提供身份验证),报文格式同Initialization Request。
      PKI主体可以是CertificationRequest(此结构由[PKCS10]中给出的ASN.1结构CertificationRequest完全指定,用于支持PKCS #10证书请求)。当需要与遗留系统进行互操作时,签名密钥对的证书请求可能需要此结构,但如果不是绝对必要,强烈建议不要使用此结构(为什么不建议呢?)。

    • Certification Response

      报文格式同Initialization Response

    • Key Update Request Content

      仍然使用CertReqMessages PKI Body,但是要包括SubjectPublicKeyInfo、KeyId和Validity字段,此消息用于请求对现有(未吊销和未过期)证书的更新(因此,有时称为“Certificate Update”操作)。更新是包含新subject公钥或当前subject公钥的替换证书(尽管后一种做法可能不适用于某些环境)。

    • Key Update Response Content

      报文格式同Initialization Response

    • Key Recovery Request Content

      报文格式同Initialization Request,但SubjectPublicKeyInfo和KeyId是必选字段可用于提供需要证书的签名公钥

    • Key Recovery Response Content

      使用以下结构作为Key Recovery Request Content的响应

          KeyRecRepContent ::= SEQUENCE {
              status          PKIStatusInfo,
              newSigCert  [0] Certificate                   OPTIONAL,
              caCerts     [1] SEQUENCE SIZE (1..MAX) OF
                                          Certificate      OPTIONAL,
              keyPairHist [2] SEQUENCE SIZE (1..MAX) OF
                                          CertifiedKeyPair OPTIONAL
          }
      
    • Revocation Request Content

      请求吊销证书
      PKI Body结构:

          RevReqContent ::= SEQUENCE OF RevDetails
      
      
          RevReqContent ::= SEQUENCE OF RevDetails
      
      
          RevDetails ::= SEQUENCE {
              certDetails         CertTemplate,
              crlEntryDetails     Extensions       OPTIONAL
          }
      
    • Revocation Response Content

      撤销响应是对上述消息的响应。如果生成,则发送给撤销请求者。(可向请求撤销的证书主体发送单独的撤销公告消息。)

          RevRepContent ::= SEQUENCE {
              status        SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
              revCerts  [0] SEQUENCE SIZE (1..MAX) OF CertId OPTIONAL,
              crls      [1] SEQUENCE SIZE (1..MAX) OF CertificateList
                          OPTIONAL
          }
      
    • Cross Certification Request Content

      请求交叉认证证书
      交叉认证请求使用与普通认证请求相同的语法(CertReqMessages),但有一个限制,即密钥对必须由请求CA生成,并且私钥不得发送到响应CA。下级CA也可以使用此请求来获取由父CA签名的证书。

    • Cross Certification Response Content

      交叉认证响应使用与正常认证响应相同的语法(CertRepMessage),但限制不能发送加密的私钥。

    • CA Key Update Announcement Content

      当CA更新其自己的密钥对时,可以使用以下数据结构来宣布此事件。

        CAKeyUpdAnnContent ::= SEQUENCE {
           oldWithNew         Certificate,
           newWithOld         Certificate,
           newWithNew         Certificate
        }
    
    • Certificate Announcement

      此结构可用于宣布证书的存在。 请注意,此消息旨在用于没有其它证书发布方法的情况;例如,如果X.500(LDAP)是发布证书的方法,则不打算使用该方法。

      CertAnnContent ::= Certificate
      
    • Revocation Announcement

      当CA已撤销或即将撤销特定证书时,它可能会发布此事件的公告。

              RevAnnContent ::= SEQUENCE {
                  status              PKIStatus,
                  certId              CertId,
                  willBeRevokedAt     GeneralizedTime,
                  badSinceDate        GeneralizedTime,
                  crlDetails          Extensions  OPTIONAL
              }
      

      CA可以使用此类公告警告(或通知)主体其证书即将(或已)被吊销。这通常用于撤销请求并非来自相关主体的情况。
      willBeRevokedAt字段包含将新条目添加到相关CRL的时间。

      • CRL Announcement
        当CA发布新的CRL(或一组CRL)时,可以使用以下数据结构来宣布此事件。
      CRLAnnContent ::= SEQUENCE OF CertificateList
      
    • PKI Confirmation Content

      此数据结构在协议交换中用作最终PKI消息。它的内容在所有情况下都是相同的——实际上没有内容,因为PKI头包含所有必需的信息。

      PKIConfirmContent ::= NULL
      

      不建议将此消息用于证书确认;应改用certConf。在收到证书响应的PKIConfirm后,接收方可以将其视Certificate Confirmation Content,并接受所有证书。

    • Certificate Confirmation Content

      客户端使用此数据结构向CA/RA发送确认以接受或拒绝证书。

          CertConfirmContent ::= SEQUENCE OF CertStatus
      
          CertStatus ::= SEQUENCE {
          certHash    OCTET STRING,
          certReqId   INTEGER,
          statusInfo  PKIStatusInfo OPTIONAL
          }
      

      对于任何特定的CertStatus,省略statusInfo字段表示接受指定的证书。或者,可以在statusInfo字段中提供明确的状态详细信息(关于接受或拒绝),可能用于CA/RA的审计目的。
      在CertConfirmContent中,省略与前一响应消息中提供的证书对应的CertStatus结构表示拒绝证书。因此,空CertConfirmContent(零长度序列)可用于指示拒绝所有提供的证书。有关占有证明的certHash字段的讨论,请参见第5.2.8节第(2)项。

    • PKI General Message Content

          InfoTypeAndValue ::= SEQUENCE {
              infoType               OBJECT IDENTIFIER,
              infoValue              ANY DEFINED BY infoType  OPTIONAL
          }
          -- where {id-it} = {id-pkix 4} = {1 3 6 1 5 5 7 4}
          GenMsgContent ::= SEQUENCE OF InfoTypeAndValue
      

      没有归类的估计都放这了吧,这部分又包含了13种报文结构

      • CA Protocol Encryption Certificate

        用于EE向CA获取证书用于保护CMP会话

        GenMsg:    {id-it 1}, < absent >
        GenRep:    {id-it 1}, Certificate | < absent >
        

        这里面的absent应该表示的是只有表示infoType的oid,没有infoValue(猜测)

      • Signing Key Pair Types

        获取CA支持的签名算法

        GenMsg:    {id-it 2}, < absent >
        GenRep:    {id-it 2}, SEQUENCE SIZE (1..MAX) OF
                AlgorithmIdentifier
        
      • Encryption/Key Agreement Key Pair Types

        获取CA的加密或KAK算法列表

        GenMsg:    {id-it 3}, < absent >
        GenRep:    {id-it 3}, SEQUENCE SIZE (1..MAX) OF
                                AlgorithmIdentifier
        
      • Preferred Symmetric Algorithm

        获取CA的首选对称加密算法

        GenMsg:    {id-it 4}, < absent >
        GenRep:    {id-it 4}, AlgorithmIdentifier
        
      • Updated CA Key Pair

        CA可用此消息宣布CA密钥对更新(直接发送,不需要请求,但需要最终实体保持监听状态)

        GenMsg:    {id-it 5}, CAKeyUpdAnnContent
        

        在RFC9480中还定义了rootCaCert消息,rootCaCert消息遵循请求/响应模型(有请求才会响应)

      • CRL
        EE用此报文获取最新的CRL

        GenMsg:    {id-it 6}, < absent >
        GenRep:    {id-it 6}, CertificateList
        
      • Unsupported Object Identifiers

        服务器使用它从客户端提交的列表中返回它不识别或不支持的对象标识符列表。
        GenRep: {id-it 7}, SEQUENCE SIZE (1..MAX) OF OBJECT IDENTIFIER

      • Key Pair Parameters

        这可由EE用于请求域参数以用于生成特定公钥算法的密钥对。例如,它可以用于请求适当的P、Q和G以生成DH/DSA密钥,或者请求一组众所周知的椭圆曲线。

        GenMsg:    {id-it 10}, OBJECT IDENTIFIER -- (Algorithm object-id)
        GenRep:    {id-it 11}, AlgorithmIdentifier | < absent >
        

        GenRep中缺少infoValue表示不支持GenMsg中指定的算法。
        EEs必须确保参数是可接受的,并且GenRep消息经过身份验证(以避免替代攻击)。
        跟openssl genpkey的-genparam选项是不是有点类似

      • Revocation Passphrase

        这可由EE用于向CA/RA发送密码短语,以便认证稍后的撤销请求(在适当的签名私钥不再可用于认证请求的情况下)。有关此机制使用的更多详细信息,请参见附录B。

        GenMsg:    {id-it 12}, EncryptedValue
        GenRep:    {id-it 12}, < absent >
        
      • ImplicitConfirm

        不发送确认消息,这个前面通用部分已经说过

      • ConfirmWaitTime

        确认超时时间,前面通用部分已经说过

      • Original PKIMessage

        RA如果修改了EE的请求,再向CA发关请求时携带的原始PKIMessage(EE向RA发送消息)

      • Supported Language Tags

        这可用于确定在后续消息中使用的适当语言标记。发送方发送其支持的语言列表(按顺序,从最优先到最不优先);接收者返回它想要使用的那个。(注意:每个UTF8String必须包含一个语言标记。)如果不支持任何提供的标记,则必须返回错误。

        GenMsg:    {id-it 16}, SEQUENCE SIZE (1..MAX) OF UTF8String
        GenRep:    {id-it 16}, SEQUENCE SIZE (1) OF UTF8String
        
    • PKI General Response Content

      对General Message的响应

          InfoTypeAndValue ::= SEQUENCE {
              infoType               OBJECT IDENTIFIER,
              infoValue              ANY DEFINED BY infoType  OPTIONAL
          }
          -- where {id-it} = {id-pkix 4} = {1 3 6 1 5 5 7 4}
          GenMsgContent ::= SEQUENCE OF InfoTypeAndValue
      
    • Error Message Content
      EE、CA或RA可以使用此数据结构来传递错误信息

          ErrorMsgContent ::= SEQUENCE {
              pKIStatusInfo          PKIStatusInfo,
              errorCode              INTEGER           OPTIONAL,
              errorDetails           PKIFreeText       OPTIONAL
          }
      

      此消息可在PKI交易期间的任何时间生成。如果客户端发送此请求,服务器必须使用PKIConfirm响应进行响应,如果标头的任何部分无效,则必须使用另一个ErrorMsg进行响应。双方必须将此消息视为会话的结束(如果会话正在进行)。
      如果需要对消息进行保护,则客户端必须使用与Initialization Request相同的技术(即签名或MAC)对其进行保护。CA必须始终使用签名密钥对其进行签名。

    • Polling Request and Response
      这对消息用于处理客户端需要轮询服务器以确定未完成的ir、cr或kur会话的状态(即,当收到“waiting”PKIStatus时)的场景。

          PollReqContent ::= SEQUENCE OF SEQUENCE {
              certReqId    INTEGER }
      
          PollRepContent ::= SEQUENCE OF SEQUENCE {
              certReqId    INTEGER,
              checkAfter   INTEGER,  -- time in seconds
              reason       PKIFreeText OPTIONAL }
      

      以下子句描述何时使用轮询消息以及如何使用它们。假定在事务期间可以发送多个certConf消息。对于包含已颁发证书的CertStatus的每个ip、cp或kup,将发送一个响应。

      1. 如果EE收到对ip、cp或kup消息的响应,将为所有已颁发的证书发送certConf,并在确认之后为所有待定证书发送pollReq。
      2. 如果CA收到pollReq,如果一个或多个挂起证书就绪,CA/RA将返回ip、cp或kup的响应;否则,它将返回一个pollRep。
      3. 如果EE收到一个pollRep,它将在发送另一个pollReq之前等待至少与checkAfter值相同的时间。
      4. 如果在pollReq响应期间接收到ip、cp或kup,会按initial response相同的方法处理
                            START
                                |
                                v
                            Send ir
                                | ip
                                v
                            Check status
                            of returned <------------------------+
                            certs                             |
                                |                               |
        

        +————————>|<——————+ |
        | | | |
        | (issued) v (waiting) | |
        Add to <----------- Check CertResponse ------> Add to |
        conf list for each certificate pending list |
        / |
        / |
        (conf list) / (empty conf list) |
        / ip |
        / +—————-+
        (empty pending list) / | pRep
        END <---- Send certConf Send pReq------------>Wait
        | ^ ^ |
        | | | |
        +—————–+ +—————+
        (pending list)

      在以下交互中,EE在一个请求中注册两个证书。

      Step  End Entity                       PKI
      --------------------------------------------------------------------
      1   Format ir
      2                    -> ir      ->
      3                                    Handle ir
      4                                    Manual intervention is
                                          required for both certs.
      5                    <- ip      <-
      6   Process ip
      7   Format pReq
      8                    -> pReq     ->
      9                                    Check status of cert requests
      10                                   Certificates not ready
      11                                   Format pRep
      12                   <- pRep     <-
      13  Wait
      14  Format pReq
      15                   -> pReq     ->
      16                                   Check status of cert requests
      17                                   One certificate is ready
      18                                   Format ip
      19                   <- ip       <-
      20  Handle ip
      21  Format certConf
      22                   -> certConf ->
      23                                   Handle certConf
      24                                   Format ack
      25                   <- pkiConf   <-
      26  Format pReq
      27                   -> pReq     ->
      28                                   Check status of certificate
      29                                   Certificate is ready
      30                                   Format ip
      31                   <- ip       <-
      31  Handle ip
      32  Format certConf
      33                   -> certConf ->
      34                                   Handle certConf
      35                                   Format ack
      36                   <- pkiConf  <-
      

    强制性的PKI功能

    这些功能是EE,RA,CA必须实现的

    • Root CA初始化

      Root CA证书必须是自签名证书,为了支持EE通过带外方式获取Root CA证书还需要生成证书指纺,用OOBCertHash结构表示

    • Root CA密钥更新

      CA密钥(与所有其他密钥一样)具有有限的生存期,必须定期更新。CA可颁发证书NewWithNew、NewWithOld和OldWithNew(见第4.4.1节),以帮助持有当前自签名CA证书(OldWithOld)的现有终端实体安全地过渡到新自签名CA证书(NewWithNew),并帮助持有NewWithNew的新终端实体安全地获取OldWithOld,以验证现有数据。

    • 下级CA(中间CA)的初始化

      从PKI管理协议的角度来看,下级CA的初始化与终端实体的初始化相同。唯一的区别是下级CA还必须生成初始吊销列表.

    • CRL生成

      新成立的CA在颁发任何证书之前必须生成每个 CRL 的“空”版本,这些版本将定期生成。

    • PKI信息请求

      当PKI实体(CA、RA或EE)希望获取有关CA当前状态的信息时,它可以向该CA发送获取此类信息的请求。请求是通过一般消息中的PKI General Message Content消息实现的,响应是通过PKI General Response Content。

    • 交叉认证

      请求者CA是将成为交叉证书subject的CA;响应者CA将成为交叉证书的issuer。

    • EE初始化

      包括获取PKI信息(Root CA证书和其它信息),和Root CA的带外验证(指纹)

    • 证书请求(初始化请求只能执行一次,后续的证书申请需要通过其它请求完成)

      已初始化的EE可随时(出于任何目的)请求额外的证书。此请求将使用证书请求(cr)消息发出。如果EE已经拥有签名密钥对(具有相应的验签证书),则该cr消息通常将受到EE数字签名的保护。CA在CertRepMessage中返回新证书(如果请求成功)。

    • 密钥更新

      当密钥对到期时,相关EE可请求密钥更新;也就是说,它可以请求CA为新密钥对颁发新证书(或者,在某些情况下,为同一密钥对颁发新证书)。使用密钥更新请求(kur)消息发出请求(在某些环境中称为“Certificate Update”操作)。如果EE已经拥有签名密钥对(具有相应的验证证书),则该消息通常将受到EE数字签名的保护。CA在密钥更新响应(kup)消息中返回新证书(如果请求成功),该消息在语法上与CertRepMessage相同。

    Views: 5

  • openssl-cmp

    openssl-cmp

    RFC 4120是v2版本(2005年),RFC 9480是V3版本(2023年),RFC 9483是轻量版本,更早的RFC 2510是V1版本,发布于1999年,现已过时。

    名字

    openssl-cmp – Certificate Management Protocol (CMP, RFC 4210) application

    概要

    openssl cmp [-help] [-config filename] [-section names] [-verbosity level]

    一般消息选项:

    [-cmd ir|cr|kur|p10cr|rr|genm] [-infotype name] [-profile name] [-geninfo values] [-template filename] [-keyspec filename]

    证书注册选项:

    [-newkey filename|uri] [-newkeypass arg] [-subject name] [-days number] [-reqexts name] [-sans spec] [-san_nodefault] [-policies name] [-policy_oids names] [-policy_oids_critical] [-popo number] [-csr filename] [-out_trusted filenames|uris] [-implicit_confirm] [-disable_confirm] [-certout filename] [-chainout filename]

    证书注册和吊销选项:

    [-oldcert filename|uri] [-issuer name] [-serial number] [-revreason number]

    消息传输选项:

    [-server [http[s]://][userinfo@]host[:port][/path][?query][#fragment]] [-proxy [http[s]://][userinfo@]host[:port][/path][?query][#fragment]] [-no_proxy addresses] [-recipient name] [-path remote_path] [-keep_alive value] [-msg_timeout seconds] [-total_timeout seconds]

    服务器认证选项:

    [-trusted filenames|uris] [-untrusted filenames|uris] [-srvcert filename|uri] [-expect_sender name] [-ignore_keyusage] [-unprotected_errors] [-no_cache_extracerts] [-srvcertout filename] [-extracertsout filename] [-cacertsout filename] [-oldwithold filename] [-newwithnew filename] [-newwithold filename] [-oldwithnew filename] [-crlcert filename] [-oldcrl filename] [-crlout filename]

    客户端认证和保护选项:

    [-ref value] [-secret arg] [-cert filename|uri] [-own_trusted filenames|uris] [-key filename|uri] [-keypass arg] [-digest name] [-mac name] [-extracerts filenames|uris] [-unprotected_requests]

    证书格式选项:

    [-certform PEM|DER] [-crlform PEM|DER] [-keyform PEM|DER|P12|ENGINE] [-otherpass arg] [-engine id] [-provider name] [-provider-path path] [-propquery propq]

    随机数状态选项:

    [-rand files] [-writerand file]

    TLS连接选项:

    [-tls_used] [-tls_cert filename|uri] [-tls_key filename|uri] [-tls_keypass arg] [-tls_extra filenames|uris] [-tls_trusted filenames|uris] [-tls_host name]

    客户端调式选项:

    [-batch] [-repeat number] [-reqin filenames] [-reqin_new_tid] [-reqout filenames] [-reqout_only filename] [-rspin filenames] [-rspout filenames] [-use_mock_srv]

    Mock server 选项:

    [-port number] [-max_msgs number] [-srv_ref value] [-srv_secret arg] [-srv_cert filename|uri] [-srv_key filename|uri] [-srv_keypass arg] [-srv_trusted filenames|uris] [-srv_untrusted filenames|uris] [-ref_cert filename|uri] [-rsp_cert filename|uri] [-rsp_crl filename|uri] [-rsp_extracerts filenames|uris] [-rsp_capubs filenames|uris] [-rsp_newwithnew filename|uri] [-rsp_newwithold filename|uri] [-rsp_oldwithnew filename|uri] [-poll_count number] [-check_after number] [-grant_implicitconf] [-pkistatus number] [-failure number] [-failurebits number] [-statusstring arg] [-send_error] [-send_unprotected] [-send_unprot_err] [-accept_unprotected] [-accept_unprot_err] [-accept_raverified]

    证书验证选项, for both CMP and TLS:

    [-allow_proxy_certs] [-attime timestamp] [-no_check_time] [-check_ss_sig] [-crl_check] [-crl_check_all] [-explicit_policy] [-extended_crl] [-ignore_critical] [-inhibit_any] [-inhibit_map] [-partial_chain] [-policy arg] [-policy_check] [-policy_print] [-purpose purpose] [-suiteB_128] [-suiteB_128_only] [-suiteB_192] [-trusted_first] [-no_alt_chains] [-use_deltas] [-auth_level num] [-verify_depth num] [-verify_email email] [-verify_hostname hostname] [-verify_ip ip] [-verify_name name] [-x509_strict] [-issuer_checks]

    描述

    cmp 命令是 RFC4210(CMP V2) 中定义的证书管理协议 (CMP) 的客户端实现。它可用于从 CA 服务器请求证书、更新其证书、请求吊销证书以及执行其他类型的 CMP 请求。

    选项

    通用选项

    • -help

      显示所有选项的摘要

    • -config filename

      指定配置文件. 空字符串 “” 表示是 none值. 默认的配置文件来自OPENSSL_CONF环境变量.

    • -section names

      配置文件中用于定义 CMP 选项的section。空字符串“”表示没有特定section。默认值为 cmp。
      可以指定多个section name,以逗号和/或空格分隔(在后一种情况下,整个参数必须括在“…”中)。后面命名的部分的内容可能会覆盖前面命名的部分的内容。无论如何,与往常一样,[default] section和最终的未命名section(就目前而言)可以提供每个选项的备用值。

    • -verbosity level

      日志记录、错误输出等的详细程度。0 = EMERG、1 = ALERT、2 = CRIT、3 = ERR、4 = WARN、5 = NOTE、6 = INFO、7 = DEBUG、8 = TRACE。默认为 6 = INFO。

    一般消息(CMP中的General Message)选项

    • -cmd ir|cr|kur|p10cr|rr|genm

      执行CMP命令. 支持以下命令:
      ir – Initialization Request
      cr – Certificate Request
      p10cr – PKCS#10 Certification Request (for legacy support)
      kur – Key Update Request
      rr – Revocation Request
      genm – General Message

      ir requests 通过颁发第一个证书将最终实体初始化到 PKI 层次结构中。

      cr requests 为已初始化到 PKI 层次结构的最终实体颁发额外证书。

      p10cr requests 颁发与 cr 类似的额外证书,但使用传统的 PKCS#10 CSR 格式发送证书请求。

      kur requests 现有证书进行密钥更新.

      rr requests 吊销现有证书.

      genm requests 使用General Message获取信息, 可以包含InfoTypeAndValues 指定哪些信息是感兴趣的. 返回的所有 infoTypes 将打印到stdout.
      cmp v2一共定义了27个报文,其中9个是请求报文,这里实现了6个请求报文,缺少了交叉证书请求,密钥恢复请求,轮询请求。

    • -infotype name

      设置用于在 genm 中请求特定信息的 InfoType 名称,例如 signKeyPairTypes。返回的内容可能会包括caCerts、rootCaCert、certReqTemplate 和 crlStatusList等字段。

    • -profile name

      证书模板的名称,放在PKIHeader的generalInfo扩展字段中

    • -geninfo values

      以逗号分隔的 InfoTypeAndValue 列表,放置在请求消息的 PKIHeader 的 generalInfo 字段中。每个 InfoTypeAndValue 都会提供一个 OID 和一个整数或字符串值,格式为 OID:int:number 或 OID:str:text,例如“1.2.3.4:int:56789, id-kp:str:name”。

    • -template filename

      用于保存通过包含id-it-certReqTemplate的genp message请求的CRMF certTemplate文件,使用DER格式保存。RFC4211字段。

    • -keyspec filename

      带id-it-keyGenParameters的genp message消息会返回keySpec,这里指定保存keySpec的文件名。RFC4211字段。
      注意:收到的任何 keySpec 字段内容都将记录为 INFO。

    Certificate enrollment options(请书注册)

    • -newkey filename|uri

      证书请求中私钥或公钥的来源,如果使用了-csr选项则从PKCS#10 CSR文件是读取。通过证书引用公钥,或指定私钥(应该只是用来算公钥)。
      密钥的公共部分会放在证书请求中。

      除非与 -cmd p10cr、-popo -1 或 -popo 0一起使用,否则也需要私钥来提供所有权证明(POPO),些时需要-key 选项(指定私钥)。

    • -newkeypass arg

      提供一个密码用于newkey指定的文文件

    • -subject name

      X.509 DN,用作 IR/CR/KUR 请求中的证书模板中的subject。如果给出了 NULL-DN (/),则模板中不会放置任何subject。默认值是使用 -csr 选项给出的任何 PKCS#10 CSR 的subject DN。对于 KUR,如果提供了参考证书(请参阅 -oldcert),则另一个后备选项是参考证书的主题 DN。仅当未设置 SAN(subject alternative name) 时,此后备选项才用于 IR 和 CR。

      如果提供了subject DN,而且没有-cert,-oldcert,-csr则会用于发出消息的subject DN。

      DN格式为/type0=value0/type1=value1/type2=...。特殊字符用\转义,允许使用空格,单个/指定空的DN,可以用+代表/作为两个RDN之间的分隔符,例如/DC=org/DC=OpenSSL/DC=users/UID=123456+CN=John Doe,/C=CN/ST=Shanghai/L=Shanghia/O=hetao/OU=RD/CN=t.he/emailAddress=t.he@hetao.me/

    • -days number

      请求新证书有效的天数,从主机的当前时间开始计算。还会触发显式请求,即有效期从当前时间(当前主机时间)开始。

    • -reqexts name

      OpenSSL 配置文件中定义证书请求扩展的section name。如果存在 -csr 选项,覆盖CSR文件中任何具有相同 OID 的扩展。

    • -sans spec

      一个或多个IP addresses, email addresses, DNS names或 URI。以逗号或空格分隔(在后一种情况下,整个参数必须括在“…”中),以添加为Subject Alternative Name(s) (SAN) 证书请求扩展。如果给出了特殊元素“critical”,则 SAN 被标记为关键。如果通过 -reqexts 设置了任何主题备用名称扩展,则无效。

    • -san_nodefault

      当未通过 -sans 或 -reqexts 定义SAN时,它们将默认从参考证书中复制(请参阅 -oldcert)。可以通过提供 -san_nodefault 选项来禁用此功能。

    • -policies name

      OpenSSL 配置文件中定义证书策略的section name。此选项不能与 -policy_oids 一起使用。

    • -policy_oids names

      一个或多个 OID,以逗号和/或空格分隔(在后一种情况下,整个参数必须括在“…”中),以添加为证书策略扩展。此选项不能与 -policies 一起使用。

    • -policy_oids_critical

      把-policy_oids给出的策略oid标记为critical

    • -popo number

      IR/CR/KUR请求的私钥所有权证明方法; values: -1..<2> where -1 = NONE, 0 = RAVERIFIED, 1 = SIGNATURE (default), 2 = KEYENC.RAVERIFIED表示RA已经证明,KEYENC表示私钥加密。
      请注意,只有通过 -newkey 或 -key 选项提供私钥时才能生成signature-based POPO。

    • -csr filename

      PKCS#10 CSR 证书请求,格式为 PEM 或 DER。使用 -cmd p10cr 时,它可直接用于旧式 P10CR 消息。
      与 -cmd ir、cr 或 kur 一起使用时,它会转换为相应的常规 CMP 请求。在这种情况下,必须提供私钥(使用 -newkey 或 -key)以证明所有权(除非使用 -popo -1 或 -popo 0),并且相应的公钥会放在认证请求中(而不是 PKCS#10 CSR 中包含的公钥)。
      PKCS#10 CSR 还可与 -cmd rr 一起使用,通过包含的subject和公钥指定要撤销的证书。如果未提供 -cert 和 -oldcert,则其subject将用作 CMP 消息头中的sender。

    • -out_trusted filenames|uris

      用于验证接收到的新注册证书的受信任证书(事先准备好的CA证书)。在此验证时,将禁用任何证书状态检查。
      可以给出多个源,用逗号和/或空格分隔(在后一种情况下,整个参数必须括在“…”中)。每个源可能包含多个证书。
      这些选项 -verify_hostname, -verify_ip, and -verify_email 只和这个选项一起使用。
      使用这个选项时证书不能包含keyUsage digitalSignature,否则会报“CMP error: certificate not accepted:rejecting newly enrolled cert with subject:…”错误。

    • -implicit_confirm

      注册证书时要求implicit confirmation(隐式确认,即不发送证书确认)

    • -disable_confirm

      请勿在没有请求隐式确认的情况下发送新注册证书的证书确认消息,以应对无法正确支持implicit confirmation选项的损坏服务器。警告:这会导致违反 RFC 4210 的行为。

    • -certout filename

      保存新证书的文件名

    • -chainout filename

      新证书的证书链. 不包括新证书也不包括trust anchor (the root certificate)。
      如果也给出了 -certout 选项,并且带有相等的文件名参数,则生成的文件会合并在一起,生成一个包含新注册的证书及其链的文件。

    Certificate enrollment and revocation options

    虽然标题为Certificate enrollment and revocation options,实际主要是Revocation和Key Update options

    • -oldcert filename|uri

      要在密钥更新请求 (KUR) 消息中更新(即续订或重新密钥化)或在撤销请求 (RR) 消息中撤销的证书。对于 KUR,要更新的证书默认为 -cert选项,生成的证书称为reference certificate。对于 RR,也可以使用 -csr 指定要撤销的证书。如果提供了 -issuer 和 -serial,则忽略 -oldcert 和 -csr。
      如果有参考证书(KUR)还用于派生默认subject DN 和SAN以及 IR/CR/KUR 请求证书模板中的默认issuer。在认证请求模板中其公钥也会使用。如果未提供 -cert,则其subject将用作传出消息的sender。如果未提供 -recipient、-srvcert 或 -issuer,则其issuer将用作 CMP 消息头中的默认recipient。

    • -issuer name

      X.509 Distinguished Name (DN) 用作 IR/CR/KUR/RR 消息中请求的证书模板中的issuer字段。如果给出 NULL-DN (/),则模板中不会放置任何issuer。
      如果已提供此选项且未给出 -recipient 或 -srvcert,则issuer DN 将用作传出 CMP 消息的recipient。
      参数格式为 /type0=value0/type1=value1/type2=….。具体参考 -subject option.

    • -serial number

      要撤销证书的序列号,可以是10进制或者16进制(0x开头)

    • -revreason number

      Set CRLReason to be included in revocation request (RR); values: 0..10 or -1 for none (which is the default).

      Reason numbers defined in RFC 5280 are:

      CRLReason ::= ENUMERATED {
      unspecified (0),
      keyCompromise (1),
      cACompromise (2),
      affiliationChanged (3),
      superseded (4),
      cessationOfOperation (5),
      certificateHold (6),
      — value 7 is not used
      removeFromCRL (8),
      privilegeWithdrawn (9),
      aACompromise (10)
      }

    Message transfer options

    • -server [http[s]://][userinfo@]host[:port][/path][?query][#fragment]

      要使用 HTTP(S) 连接的 CMP 服务器的域名或IP 地址以及可选的端口号。IP 地址可以是 v4 或 v6,例如 127.0.0.1 或 [::1] 表示 localhost。如果主机字符串是 IPv6 地址,则必须用 [ 和 ] 括起来。

      此选项不能与 -port 和 -use_mock_srv共存。如果 -rspin 带有足够的文件名参数,则会忽略此选项。

      如果给出了 https,则隐含 -tls_used 选项。使用 TLS 时,默认端口为 443,否则为 80。可选的 userinfo 和 fragment 组件将被忽略。任何给定的query组件都作为path组件的一部分处理。如果包含path,它将为 -path 选项提供默认值。

    • -proxy [http[s]://][userinfo@]host[:port][/path][?query][#fragment]

      用于访问 CMP 服务器的 HTTP(S) 代理服务器(-no_proxy匹配的域名除外。如果主机字符串是 IPv6 地址,则必须将其括在 [ 和 ] 中。如果scheme为 https,则代理端口默认为 80 或 443;除非可选的 http:// 或 https:// 前缀没有指定(请注意,如果要使用TLS则需要-tls_used 或 -server 带有前缀 https ),以及任何path、userinfo、query和fragment组件也可以忽略。
      默认使用境变量 http_proxy的值,如果使用 TLS,则为 HTTPS_PROXY。
      如果未给出 -server,则忽略此选项。

    • -no_proxy addresses

      不使用 HTTP(S) 代理的服务器的 IP 地址和/或 DNS 名称列表,以逗号和/或空格分隔(在后一种情况下,整个参数必须括在“…”中)。如果设置了环境变量 no_proxy,则默认值为 NO_PROXY的值。如果未指定 -server,则忽略此选项。

    • -recipient name

      Distinguished Name (DN) 用于 CMP request message headers 的recipient字段, i.e., the CMP server (通常是CA).

      recipient 字段在CMP message 的头部是必须的. 如果没有明确给出,则按以下顺序确定recipient:使用 -srvcert 选项给出的 CMP 服务器证书的subject、-issuer 选项、使用 -oldcert 选项给出的证书的issuer、CMP 客户端证书(-cert 选项)的issuer(如果存在的话),否则将使用 NULL-DN 作为最后的手段。

      格式为 /type0=value0/type1=value1/type2=…. 参考 -subject option.

    • -path remote_path

      CMP 服务器(又名 CMP alia)上用于 POST 请求的 HTTP url path。默认为 -server 指定的任何path,否则为“/”。

    • -keep_alive value

      如果给定值为 0,则 HTTP 连接在每次响应后都会关闭(这是 HTTP 1.0 的默认行为),即使 CMP 事务需要多次往返也是如此。如果值为 1 或 2,则每次事务都会请求持久连接。如果值为 2,则强制持久连接,即如果服务器不支持,则会出现错误。默认值为 1,表示倾向于保持连接打开。

    • -msg_timeout seconds

      在返回超时错误之前,CMP 请求-响应消息往返允许的秒数。值 <= 0 表示没有限制(无限期等待)。默认使用 -total_timeout 设置。

    • -total_timeout seconds

      会话可能需要的最大总秒数,包括轮询等。值 <= 0 表示无限制(无限期等待)。默认值为 0。

    服务器认证选项

    • -trusted filenames|uris

      root CA证书, client使用这个作为 trust anchors 当验证 signature-based 保护的CMP响应消息. 如果-srvcert选项存在这个选项是忽略的。它比 -srvcert 提供了更大的灵活性,因为服务器的 CMP 保护证书不是固定的,而是可以是信任证书链中任何到tust anchor之间的证书。
      如果没有-trusted, -srvcert, and -secret , message validation errors 会抛出,除非指定 -unprotected_errors 忽略 exception.
      可以给出多个filename,用逗号和/或空格分隔(在后一种情况下,整个参数必须括在“…”中)。每个源可能包含多个证书。
      如果这个选项指定,则证书验证相关的选项 -verify_hostname, -verify_ip, and -verify_email 不生效。

    • -untrusted filenames|uris

      Non-trusted intermediate CA certificate(s). Any extra certificates given with the -cert option are appended to it. All these certificates may be useful for cert path construction for the own CMP signer certificate (to include in the extraCerts field of request messages) and for the TLS client certificate (if TLS is used) as well as for chain building when validating server certificates (checking signature-based CMP message protection) and when validating newly enrolled certificates.
      非信任中间 CA 证书。使用 -cert 选项提供的任何额外证书都将附加到该证书。用于构建自己的 CMP 签名者证书的证书链(以包含在请求消息的 extraCerts 字段中)和 TLS 客户端证书(如果使用 TLS),以及在验证服务器证书(检查基于签名的 CMP 消息保护)和验证新注册的证书时构建证书链。
      可以给出多个源,用逗号和/或空格分隔(在后一种情况下,整个参数必须括在“…”中)。每个源可能包含多个证书。
      基于以上这里的untrusted并不是说证书不受信任,而是在信任证书以外但又需要提供的证书。

    • -srvcert filename|uri
      在验证 CMP 响应消息的基于签名的保护时,需要并直接信任的 CMP 服务器证书(即使该证书已过期)。这会固定CMP服务器并导致忽略 -trusted 选项。
      如果设置,证书的subject也将用作 CMP 请求recipient的默认值以及 CMP 响应预期sender的默认值。
      服务器接收到的新注册证书也可以使用-srvcert指定的证书进行验证(这样就不用指定-out_trusted选项了)

    • -expect_sender name

      接到的CMP响应的发件人字段中应包含专有名称 (DN)。默认为 -srvcert 的subject DN(如果有)。
      这可用于确保只有特定实体被接受为 CMP 消息签名者,并且攻击者无法使用受信任 PKI 层次结构的任意证书来冒充 CMP 服务器。请注意,此选项比设置 -srvcert 稍微自由一些,后者将服务器固定到特定证书的持有者,而预期的sender名称在服务器证书更新后将继续匹配。
      参数格式为 /type0=value0/type1=value1/type2=…. For details see the description of the -subject option.

    • -ignore_keyusage

      验证传入 CMP 消息的基于签名的保护时,忽略 CMP 签名者证书中的密钥使用限制。默认情况下,CMP 签名者证书必须允许 digitalSignature。此选项适用于 CMP 客户端和模拟服务器(mock server)。

    • -unprotected_errors

      接受服务器缺失或无效的响应保护。这适用于以下消息类型和内容:
      error messages
      negative certificate responses (IP/CP/KUP)
      negative revocation responses (RP)
      negative PKIConf messages
      警告:此设置会导致未指定的行为,它仅用于允许与违反 RFC 4210 的服务器实现互操作,例如:
      第 5.1.3.1 节仅允许在特殊情况下保护例外:“可能存在故意不使用 PKIProtection BIT STRING 来保护消息 […] 因为将改为应用 PKIX 之外的其他保护的情况。”
      第 5.3.21 节对 ErrMsgContent 进行了明确规定:“CA 必须始终使用签名密钥对其进行签名。”
      附录 D.4 显示 PKIConf 消息具有保护

    • -no_cache_extracerts

      不缓存 CMP 消息的 extraCerts 字段中的证书。默认情况下,它们会被保留,因为它们可能有助于验证后续消息。此选项适用于 CMP 客户端和模拟服务器。

    • -srvcertout filename

      保存已成功验证(-out_trusted选项验证还是消息保护验证?)的证书(如果有)的文件,如果服务器使用基于签名保护的响应消息则会存在这样的证书。如果没有此类证书(通常是因为保护是基于 MAC 的),则会删除该文件(如果存在)。

    • -extracertsout filename

      收到的的响应消息的 extraCerts 字段中包含的证书列表(pollRep,PKIConf除外),则保存到filename。没有中间CA证书时跟-srvcertout的内容是一样的。

    • -cacertsout filename

      如果收到了正确的证书响应(即 IP、CP 或 KUP)消息,或者该消息包含在通用响应(genp)消息的caCerts infoType字段中的证书列表,则保存到filename

    • -oldwithold filename

      EE当前持有的root CA证书放到genm请求的rootCaCert infoType中,如果收到oldWithNew证书由则以newWithNew作为新的trust anchor(信任证书)
      old with new CA创建的包含使用新私钥签名的旧CA公钥的证书
      nenw with old CA创建的包含使用旧私钥签名的新CA公钥的证书
      new with new CA创新的包含使用新私钥签名的新CA公钥
      old with old EE持有的当前自签名CA证书
      这个rootCaCert genm请求包括下面的几个证书返回值,在RFC4210(CMP V2)中并没有,而是在RFC9480中定义的,这是不是写串了。开头明明说这个命令是RFC4210的实现。
      该请求用于获取新的CA证书。
      这个请求的asn.1代码

      GenMsg:    {id-it 20}, RootCaCertValue | < absent >
      GenRep:    {id-it 18}, RootCaKeyUpdateContent | < absent >
      
      RootCaCertValue ::= CMPCertificate
      
      RootCaKeyUpdateValue ::= RootCaKeyUpdateContent
      
      RootCaKeyUpdateContent ::= SEQUENCE {
          newWithNew       CMPCertificate,
          newWithOld   [0] CMPCertificate OPTIONAL,
          oldWithNew   [1] CMPCertificate OPTIONAL
      }
      

      注意:与 CAKeyUpdAnnContent 相比,此类型提供在 GenRep 消息中省略 newWithOld 和 oldWithNew 的功能,具体取决于 EE 的需求。

    • -newwithnew filename

      当使用-oldwithold的时候这个选项用于保存收到的newWithNew证书,如果没有收到newIwthNew证书,则删除filename指定的文件,同时rootCA的密钥更新失败。
      任何收到的 newWithNew 证书都使用任何收到的 newWithOld 证书作为不受信任的中间证书,并使用 -oldwithold 提供的证书作为(唯一)信任锚进行验证,如果未提供,则使用 -trusted 选项提供的证书。

      警告:newWithNew 证书应为受信任的证书。如果存在 -oldwithold 证书,则对其的信任度不能高于-oldwithold指定的证书,也不能高于对任何 -trusted 证书的最弱信任度。

    • -newwithold filename

      该文件用于保存在 genp 消息infoType rootCaKeyUpdate中的的任何 newWithOld 证书。如果未收到此类证书,则删除文件。

    • -oldwithnew filename

      用于保存在 genp 消息infoType rootCaKeyUpdate中的任何 oldWithNew 证书的文件。如果成功时未收到此类证书,则通过删除文件来表示。

    • -crlcert filename

      在具有 infoType crlStatusList 的 genm 消息中请求 通过证书指定CRL issuer。如果指定的DistributionPointName优先于指定证书的issuer名称。
      这个也是RFC9480中的消息类型,通过指定DistributionPointName或issuer来表示EE现有的CRL文件,应返回一个更新的CRL文件。
      asn.1代码

      “`asn.1
      GenMsg: {id-it 22}, SEQUENCE SIZE (1..MAX) OF CRLStatus
      GenRep: {id-it 23}, SEQUENCE SIZE (1..MAX) OF
      CertificateList | < absent >

      CRLSource ::= CHOICE {
      dpn [0] DistributionPointName,
      issuer [1] GeneralNames }

      CRLStatus ::= SEQUENCE {
      source CRLSource,
      thisUpdate Time OPTIONAL }

      “`

    • -oldcrl filename

      在包含infoType crlStatusList的genm消息中通过现有CRL文件指定 CRL issuer。
      任何可用的DistributionPointName都优先于issuer名称。如果还给出了 -crlcrt,则其数据优先于 -oldcrl 中的数据。

    • -crlout filename

      用于保存在 genp 消息crls infType 中收到的 CRL文件。如果成功时未收到此类 CRL,则通过删除文件来表示。

    Client authentication options

    • -ref value

      参考值
      参考 number/string/value 作为 senderKID 的值(相当于用户名);如果无法从 -cert 或 <-subject> 选项中确定sender名称,则需要此项,并且通常在使用预共享密钥(password-based MAC)进行身份验证时使用。

    • -secret arg

      秘密值
      提供用于MAC-based message protection的秘密值的来源。这优先于 -cert 和 -key 选项。该密钥用于创建MAC-based protection的传出消息以及验证具有MAC-based protection的传入消息。默认使用的算法是Password-Based Message Authentication Code (PBM),如 RFC 4210 第 5.1.3.1 节中定义。
      For more information about the format of arg see openssl-passphrase-options(1).

    • -cert filename|uri

      客户端当前的 CMP signer certificate. 其私钥通过 -key 指定.
      该证书中包含的subject和公钥作为 IR/CR/KUR 消息的证书模板。
      该证书的subject将用作传出 CMP 消息的sender,而 -oldcert 或 -subjectName 的主题可能提供后备值。
      该证书的issuer用作recipient后备值之一,并用作 IR/CR/KUR 消息的证书模板中的后备issuer条目。
      在执行signature-based message protection时,此“protection certificate”(也称为“signer certificate”)将首先包含在传出消息的 extraCerts 字段中,并使用相应的私钥进行签名。在初始化请求 (IR) 消息中,这可用于使用 RFC 4210 附录 E.7 中定义的外部实体证书进行身份验证。
      对于密钥更新请求 (KUR) 消息,如果未给出 -oldcert 选项,这也用作要更新的证书。
      如果文件还包含其它的证书,它们将被附加到untrusted certs中,因为它们通常构成客户端证书链,该证书链包含在受签名保护的请求消息中的 extraCerts 字段中。

    • -own_trusted filenames|uris

      如果提供了此证书列表,则使用给定的证书作为trust anchors构建证书链来验证使用 -cert 选项给出的客户端 CMP signer certificate。
      可以给出多个源,用逗号和/或空格分隔(在后一种情况下,整个参数必须括在“…”中)。每个源可能包含多个证书。
      certificate verification options -verify_hostname、-verify_ip 和 -verify_email 对通过此选项启用的证书验证没有影响。

    • -key filename|uri

      The corresponding private key file for the client’s current certificate given in the -cert option. This will be used for signature-based message protection unless the -secret option indicating MAC-based protection or -unprotected_requests is given.
      -cert 选项中给出的客户端当前证书的相应私钥文件。除非通过-secret指定MAC-based protection或 指定了-unprotected_requests,否则这将用于signature-based message protection。
      它还可用作 IR/CR/KUR 消息的 -newkey 选项的后备。

    • -keypass arg

      指定 -key 选项的私钥的密码。如果是加密的 PKCS#12 文件,也用于 -cert 和 -oldcert。如果此处未指定,则在需要时会提示输入密码。
      For more information about the format of arg see openssl-passphrase-options(1).

    • -digest name

      指定在 RFC 4210 的 MSG_SIG_ALG 中使用的受支持摘要算法的名称,以及在 MSG_MAC_ALG 中用作one-way function (OWF) 的名称。如果适用,则用于proof-of-possession (POPO) 签名。要查看受支持的摘要算法列表,请使用 openssl list -digest-commands。默认为 sha256。

    • -mac name

      指定 MSG_MAC_ALG 中的 MAC 算法的名称。要获取受支持的 MAC 算法的名称,请使用 openssl list -mac-algorithms,并可能将此类名称与受支持的摘要算法的名称相结合,例如 hmacWithSHA256。根据 RFC 4210,默认为 hmac-sha1。

    • -extracerts filenames|uris

      发送消息时附加在 extraCerts 字段中的证书。它们可用作要包含的默认 CMP signer certificate chain。
      可以给出多个源,用逗号和/或空格分隔(在后一种情况下,整个参数必须括在“…”中)。每个源可能包含多个证书。

    • -unprotected_requests

      发送消息不使用 CMP-level protection.

    Credentials format options

    • -certform PEM|DER

      将证书保存到文件时使用的文件格式。默认值为 PEM。

    • -crlform PEM|DER

      将 CRL 保存到文件时使用的文件格式。默认值为 DER。DER 格式是首选格式,因为它可以更有效地存储大型 CRL。

    • -keyform PEM|DER|P12|ENGINE

      私钥输入的格式;默认情况下未指定。有关详细信息,请参阅 openssl(1) 中的“Format Options”。

    • -otherpass arg

      其它指定证书的密钥,包括 -trusted, -untrusted, -own_trusted, -srvcert, -crlcert, -out_trusted, -extracerts, -srv_trusted, -srv_untrusted, -ref_cert, -rsp_cert, -rsp_extracerts, -rsp_capubs, -rsp_newwithnew, -rsp_newwithold, -rsp_oldwithnew, -tls_extra, and -tls_trusted 选项. 如果此处未指定,则在需要时会提示输入密码。

    • -engine id

      参考 “Engine Options” in openssl(1). 这个选项已废弃。
      通过以下值的组合来指定:
      -engine {engineid} -key {keyid} -keyform ENGINE
      也可以用-key选项指定一个URI格式的key ID
      -key org.openssl.engine:{engineid}:{keyid}
      应用于所有指定私钥的选项: -key, -newkey, and -tls_key.

    Provider options

    • -provider name
    • -provider-path path
    • -propquery propq

    Random state options

    • -rand files, -writerand file

    TLS connection options

    • -tls_used

      让 CMP 客户端使用 TLS(无论是否设置了其他与 TLS 相关的选项)与 HTTP 与服务器交换消息。-port 选项不支持此选项。如果使用 https 方案指定了 -server 选项,则隐含此选项。如果未指定 -server 选项或指定了 -use_mock_srv 或指定了带有足够文件名参数的 -rspin,则会忽略此选项。
      如果不使用 TLS,则会忽略以下与 TLS 相关的选项。

    • -tls_cert filename|uri

      用于连接 TLS 服务器时进行身份验证的客户端 TLS 证书。如果filename还包含其他证书,则-untrusted certs指定的证书将用于构建提供给 TLS 服务器的客户端证书链。

    • -tls_key filename|uri

      证书私钥

    • -tls_keypass arg

      客户端TLS私钥 -tls_key 的密码源。如果是加密的 PKCS#12 文件,也用于 -tls_cert。如果此处未提供,则在需要时会提示输入密码。
      For more information about the format of arg see openssl-passphrase-options(1).

    • -tls_extra filenames|uris

      TLS握手期间向服务器提供的额外证书。

    • -tls_trusted filenames|uris

      用于验证 TLS 服务器证书的Trusted certificate(s)。这意味着主机名验证。
      可以给出多个源,用逗号和/或空格分隔(在后一种情况下,整个参数必须括在“…”中)。每个源可能包含多个证书。
      证书验证选项 -verify_hostname、-verify_ip 和 -verify_email 对通过此选项启用的证书验证没有影响。

    • -tls_host name

      hostname validation期间要检查的地址。这可能是 DNS 名称或 IP 地址。如果未指定,则默认为 -server 地址。

    Client-side options for debugging and offline scenarios

    • -batch

      不要以交互方式提示输入,例如当需要密码时。这对于批处理和测试很有用。

    • -repeat number

      使用相同参数调用命令给定的次数。默认为一次调用。

    • -reqin filenames

      从给定的文件(而不是内部生成的请求序列)中获取要发送到服务器的 CMP 请求序列。
      此选项对于支持离线场景很有用,在这种场景中,证书请求(或任何其他 CMP 请求)是预先生成并稍后发送的。
      如果给出了 -rspin 选项,则会忽略此选项,因为在后一种情况下实际上没有发送任何请求。
      请注意,在任何情况下,客户端都会在内部生成其 CMP 请求消息序列。因此,当存在 -reqin 选项时,还需要提供执行此操作所需的所有选项(例如 -cmd 和为其提供所需参数的所有选项)。
      如果为证书请求提供了 -reqin 选项,并且未提供 -newkey、-key、-oldcert 或 -csr 选项,则从请求消息文件中获取后备公钥(如果它包含在证书模板中)。
      提示:如果为证书请求提供了 -reqin 选项,则在某些情况下,默认情况下需要用于POPO的私钥,但是客户端可以访问公钥,但无法访问私钥,在这种情况下,POPO 实际上不是必需的(因为内部生成的certificate request消息不会发送),并且可以使用选项 -popo -1 或 -popo 0 禁用其生成。
      可以给出多个文件名,用逗号和/或空格分隔(在后一种情况下,整个参数必须括在“…”中)。
      The files are read as far as needed to complete the transaction and filenames have been provided. If more requests are needed, the remaining ones are taken from the items at the respective position in the sequence of requests produced internally.
      读取提供的文件以完成会话。如果需要更多请求,则剩余的请求将从内部生成的请求序列中相应位置的项目中获取。
      客户端需要更新给定请求中的 recipNonce 字段(第一个请求除外),以满足服务器要执行的检查。这会导致re-protection(if protecting requests is required)。

    • -reqin_new_tid

      使用 -reqin 读取 CMP 请求消息时使用新的 transactionID,这会导致reprotection这些消息(如果需要保护请求)。如果请求序列被重用,并且 CMP 服务器抱怨事务 ID 已被使用,则可能需要这样做。

    • -reqout filenames

      Save the sequence of CMP requests created by the client to the given file(s). These requests are not sent to the server if the -reqin option is used, too.(-reqout和-reqin能同时用吗)
      将客户端创建的 CMP 请求序列保存到给定的文件中。如果使用了 -reqin 选项,则不会将这些请求发送到服务器。
      可以指定多个文件名,以逗号和/或空格分隔。
      根据需要写入文件以保存会话。如果事务包含更多请求,则不会保存剩余的请求。

    • -reqout_only filename

      将客户端创建的第一个 CMP 请求保存到给定文件并退出。与 CMP 服务器及其响应相关的任何选项都将被忽略。
      此选项对于支持离线场景很有用,在离线场景中,证书请求(或任何其他 CMP 请求)是预先生成的,稍后再发送。

    • -rspin filenames

      处理给定文件中提供的 CMP 响应序列,不联系任何给定的服务器,只要提供足够的文件名来完成会话即可。
      可以给出多个文件名,以逗号和/或空格分隔。
      仅当需要更多响应来完成事务时,才会联系通过 -server 或 -use_mock_srv 选项指定的任何服务器。在这种情况下,除非服务器已准备好继续已存在的会话,否则会话将失败。

    • -rspout filenames

      将实际使用的 CMP 响应序列保存到给定的文件中。除非 -rspin 生效,否则这些响应是从服务器接收的。
      可以给出多个文件名,以逗号和/或空格分隔。
      写入提供的文件以保存事务中包含的响应。如果事务包含更多响应,则不会保存其余响应。

    • -use_mock_srv

      使用 API 级别的内部 CMP 服务器模型测试客户端,绕过基于套接字的 HTTP 传输。这不包括 -server 和 -port 选项。(直接调用C API吗)

    Mock server options

    CMP模拟服务器(为什么不弄个真的)
    
    • -port number

      充当基于 HTTP 的 CMP 服务器模拟,监听给定的本地端口。客户端可以通过 127.0.0.1 或 [::1] 等地址来访问服务器。此选项不能与 -server 和 -use_mock_srv 选项共存。到目前为止,此模式不支持 -rspin、-rspout、-reqin 和 -reqout 选项。

    • -max_msgs number

      CMP HTTP 服务器模型应处理的最大 CMP(请求)消息数,该值必须为非负数。默认值为 0,表示不设限制。在任何情况下,服务器都会因内部错误而终止,但当检测到 CMP-level 错误并能成功用错误消息进行应答时不会终止。

    • -srv_ref value

      在没有给出 -srv_cert 的情况下用作服务器的 senderKID 的参考值。

    • -srv_secret arg

      使用预共享密钥(秘密值)进行服务器身份验证的密码。

    • -srv_cert filename|uri

      CMP服务器的证书(CA证书)

    • -srv_key filename|uri

      服务器用于签名消息的私钥(也是-srv_cert filename的私钥)。

    • -srv_keypass arg

      服务器私钥(和证书)文件密码

    • -srv_trusted filenames|uris

      Trusted certificates for client authentication.
      客户端认证时的可信证书

      此时以下证书验证选项是不生效的: -verify_hostname, -verify_ip, and -verify_email.

    • -srv_untrusted filenames|uris

      验证客户端证书的中间CA证书

    • -ref_cert filename|uri

      RR(revocation request) messages 引用的证书以及KUR(Key Update Request) messages的oldCertID.

    • -rsp_cert filename|uri

      模拟注册证书时返回的证书

    • -rsp_crl filename|uri

      crls genp请求返回的CRL文件

    • -rsp_extracerts filenames|uris

      模拟证书响应中的Extra certificates

    • -rsp_capubs filenames|uris

      模拟的Initialization Response (IP) message中的CA证书

    • -rsp_newwithnew filename|uri

      rootCaKeyUpdate genp消息中newWithNew字段的证书

    • -rsp_newwithold filename|uri

      rootCaKeyUpdate genp消息中newWithOld字段的证书

    • -rsp_oldwithnew filename|uri

      rootCaKeyUpdate genp消息中oldWithNew字段的证书

    • -poll_count number

      客户端在收到证书之前必须轮询的次数(故意延迟返回)。

    • -check_after number

      轮询响应消息中的checkAfter value (number of seconds to wait)

    • -grant_implicitconf

      注册证书时接受implicit confirmation

    • -pkistatus number

      包含在服务器响应中的PKIStatus。有效范围是 0(accepted)… 6(keyUpdateWarning)。

    • -failure number

      服务器响应中要包含的单个故障信息bit位置。bit位置的有效范围是 0 (badAlg) … 26 (duplicateCertReq)。

    • -failurebits number

      number 表示failure的10进制值. 范围是 0 … 2^27 – 1.

    • -statusstring arg

      作为status string包含在服务器响应中的Text(free text?)。

    • -send_error

      强制服务器返回错误

    • -send_unprotected

      发送一个不带CMP-level protection的响应消息

    • -send_unprot_err

      如果出现不良响应,服务器将发送unprotected(不带CMP-level protection) 的error messages、证书响应 (IP/CP/KUP) 和撤销响应 (RP)。警告:此设置会导致违反 RFC 4210 的行为。

    • -accept_unprotected

      接受无保护/无效保护的请求

    • -accept_unprot_err

      接受来自客户端的unprotected的错误消息。到目前为止,这没有任何效果,因为服务器不接受任何错误消息。

    • -accept_raverified

      接受RAVERIFED所有权证书(POPO)的值.

    Certificate verification options

    对CMP and TLS都有效的选项:-allow_proxy_certs, -attime, -no_check_time, -check_ss_sig, -crl_check, -crl_check_all, -explicit_policy, -extended_crl, -ignore_critical, -inhibit_any, -inhibit_map, -no_alt_chains, -partial_chain, -policy, -policy_check, -policy_print, -purpose, -suiteB_128, -suiteB_128_only, -suiteB_192, -trusted_first, -use_deltas, -auth_level, -verify_depth, -verify_email, -verify_hostname, -verify_ip, -verify_name, -x509_strict -issuer_checks。
    证书链验证的各种 “Verification Options” in openssl-verification-options(1) for details.
    证书验证选项 -verify_hostname、-verify_ip 和 -verify_email 仅影响通过 -out_trusted 选项启用的证书验证。

    NOTES

    当客户端从 CMP 服务器获取要信任的 CA 证书时(例如通过general messages caCerts 或 rootCACert infoType的响应),CMP 服务器的身份验证尤为重要。因此,在使用certificate-based authentication或使用 -secret 进行MAC-based protection时必须特别小心使用 -trusted 和相关选项进行来设置服务器身份验证。如果身份验证是基于证书的,则应使用 -srvcertout 选项获取经过验证的服务器证书并基于该证书执行authorization check(检查谁?)。
    在设置 CMP 配置和试验证书注册选项时,通常会发生各种错误,直到配置正确且完整。当 CMP 服务器报告错误时,客户端将默认检查 CMP 响应消息的保护。然而,一些 CMP 服务往往不保护不良响应(negative responses)。在这种情况下,客户端将拒绝它们,因此不会显示它们的内容,尽管它们通常包含有助于诊断的提示。为了帮助解决此类情况,CMP 客户端通过 -unprotected_errors 选项提供了一种解决方法,允许接受此类negative responses。
    如果 OpenSSL 是在启用跟踪支持的情况下构建的(例如,./config enable-trace),并且环境变量 OPENSSL_TRACE 包含 HTTP,则会打印通过 HTTP 传输的请求和响应标头。

    Views: 2

  • CMP V2协议(RFC4210)

    CMP(Certificate Management Protocol)是由IETF开发的协议,用于证书管理,包括证书申请、更新、撤销等。CMP协议的标准由IETF的RFC 4210定义。CMP协议消息的格式基于ASN.1(Abstract Syntax Notation One)描述,并使用DER(Distinguished Encoding Rules)进行编码。
    RFC4210定义的是CMP V2,最新的CMP V3(RFC9480)也已经发布了。
    以下是关于CMP协议格式的详细说明:

    1. CMP协议消息的基本结构

    CMP协议消息的基本结构由以下几个部分组成:

    1.1. PKIMessage

    PKIMessage是CMP协议的基本消息类型,包含了所有CMP消息的通用结构。其ASN.1描述如下:

    “`asn.1
    PKIMessage ::= SEQUENCE {
    header PKIHeader,
    body PKIBody,
    protection [0] PKIProtection OPTIONAL,
    extraCerts [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate OPTIONAL
    }

    <pre><code class="line-numbers">- **header**:PKIHeader,包含消息的元数据,如消息类型、发送者和接收者信息等。
    – **body**:PKIBody,包含实际的消息内容,如证书请求、证书响应等。
    – **protection**:PKIProtection,可选字段,用于保护消息的完整性和真实性。
    – **extraCerts**:SEQUENCE OF CMPCertificate,可选字段,包含额外的证书。

    ### 1.2. PKIHeader

    PKIHeader包含消息的元数据,其ASN.1描述如下:

    “`asn.1
    PKIHeader ::= SEQUENCE {
    pvno INTEGER { cmp1999(1), cmp2000(2) },
    sender GeneralName,
    recipient GeneralName,
    messageTime [0] GeneralizedTime OPTIONAL,
    protectionAlg [1] AlgorithmIdentifier OPTIONAL,
    senderKID [2] KeyIdentifier OPTIONAL,
    recipKID [3] KeyIdentifier OPTIONAL,
    transactionID [4] OCTET STRING OPTIONAL,
    senderNonce [5] OCTET STRING OPTIONAL,
    recipNonce [6] OCTET STRING OPTIONAL,
    freeText [7] PKIFreeText OPTIONAL,
    generalInfo [8] SEQUENCE SIZE (1..MAX) OF InfoTypeAndValue OPTIONAL
    }

    • pvno:协议版本号。
    • sender:发送者的标识。
    • recipient:接收者的标识。
    • messageTime:消息的时间戳(可选)。
    • protectionAlg:用于保护消息的算法标识符(可选)。
    • senderKID:发送者的密钥标识符(可选)。
    • recipKID:接收者的密钥标识符(可选)。
    • transactionID:事务ID(可选)。
    • senderNonce:发送者的随机数(可选)。
    • recipNonce:接收者的随机数(可选)。
    • freeText:自由文本(可选)。
    • generalInfo:一般信息(可选)。

    1.3. PKIBody

    PKIBody包含实际的消息内容,其ASN.1描述如下:

    “`asn.1
    PKIBody ::= CHOICE {
    ir [0] CertReqMessages, — Initialization Request
    ip [1] CertRepMessage, — Initialization Response
    cr [2] CertReqMessages, — Certification Request
    cp [3] CertRepMessage, — Certification Response
    p10cr [4] CertificationRequest, — PKCS #10 Certificate Request
    popdecc [5] POPODecKeyChallContent, — Proof-of-Possession Challenge
    popdecr [6] POPODecKeyRespContent, — Proof-of-Possession Response
    kur [7] CertReqMessages, — Key Update Request
    kup [8] CertRepMessage, — Key Update Response
    krr [9] CertReqMessages, — Key Recovery Request
    krp [10] KeyRecRepContent, — Key Recovery Response
    rr [11] RevReqContent, — Revocation Request
    rp [12] RevRepContent, — Revocation Response
    ccr [13] CertReqMessages, — Cross-Certification Request
    ccp [14] CertRepMessage, — Cross-Certification Response
    ckuann [15] CAKeyUpdAnnContent, — CA Key Update Announcement
    cann [16] CertAnnContent, — Certificate Announcement
    rann [17] RevAnnContent, — Revocation Announcement
    crlann [18] CRLAnnContent, — CRL Announcement
    pkiconf [19] PKIConfirmContent, — Confirmation
    nested [20] NestedMessageContent, — Nested Message
    genm [21] GenMsgContent, — General Message
    genp [22] GenRepContent, — General Response
    error [23] ErrorMsgContent, — Error Message
    certConf [24] CertConfirmContent, — Certificate Confirmation
    pollReq [25] PollReqContent, — Polling Request
    pollRep [26] PollRepContent — Polling Response
    }

    <pre><code class="line-numbers">- **ir**:初始化请求(Initialization Request)。
    – **ip**:初始化响应(Initialization Response)。
    – **cr**:认证请求(Certification Request)。
    – **cp**:认证响应(Certification Response)。
    – **p10cr**:PKCS #10证书请求(PKCS #10 Certificate Request)。
    – **popdecc**:证明密钥拥有权挑战(Proof-of-Possession Challenge)。
    – **popdecr**:证明密钥拥有权响应(Proof-of-Possession Response)。
    – **kur**:密钥更新请求(Key Update Request)。
    – **kup**:密钥更新响应(Key Update Response)。
    – **krr**:密钥恢复请求(Key Recovery Request)。
    – **krp**:密钥恢复响应(Key Recovery Response)。
    – **rr**:撤销请求(Revocation Request)。
    – **rp**:撤销响应(Revocation Response)。
    – **ccr**:交叉认证请求(Cross-Certification Request)。
    – **ccp**:交叉认证响应(Cross-Certification Response)。
    – **ckuann**:CA密钥更新公告(CA Key Update Announcement)。
    – **cann**:证书公告(Certificate Announcement)。
    – **rann**:撤销公告(Revocation Announcement)。
    – **crlann**:CRL公告(CRL Announcement)。
    – **pkiconf**:确认(Confirmation)。
    – **nested**:嵌套消息(Nested Message)。
    – **genm**:一般消息(General Message)。
    – **genp**:一般响应(General Response)。
    – **error**:错误消息(Error Message)。
    – **certConf**:证书确认(Certificate Confirmation)。
    – **pollReq**:轮询请求(Polling Request)。
    – **pollRep**:轮询响应(Polling Response)。

    ## 2. CMP协议消息的保护

    CMP协议消息可以通过PKIProtection字段进行保护,确保消息的完整性和真实性。PKIProtection字段的ASN.1描述如下:

    “`asn.1
    PKIProtection ::= BIT STRING

    • PKIProtection:包含消息的保护信息,通常是消息的签名或MAC(消息认证码)。

    3. CMP协议消息的编码

    CMP协议消息使用ASN.1描述,并通过DER(Distinguished Encoding Rules)进行编码。DER是一种二进制编码规则,确保消息的唯一编码。

    4. 示例:CMP协议消息

    以下是一个简单的CMP协议消息示例,展示了初始化请求(Initialization Request)的结构:

    “`asn.1
    PKIMessage ::= SEQUENCE {
    header PKIHeader {
    pvno cmp2000,
    sender GeneralName { directoryName { rdnSequence { commonName "Client" } } },
    recipient GeneralName { directoryName { rdnSequence { commonName "CA" } } },
    messageTime GeneralizedTime "20230101000000Z",
    senderNonce OCTET STRING "1234567890abcdef",
    transactionID OCTET STRING "abcdef1234567890"
    },
    body PKIBody {
    ir CertReqMessages {
    CertReqMsg {
    certReq CertRequest {
    certReqId INTEGER 1,
    certTemplate CertTemplate {
    version Version v3,
    subject Name { rdnSequence { commonName "Client" } },
    publicKey SubjectPublicKeyInfo { algorithm { algorithm rsaEncryption }, subjectPublicKey BIT STRING "…" }
    }
    },
    popo ProofOfPossession { raVerified },
    regInfo SEQUENCE { }
    }
    }
    },
    protection PKIProtection "…"
    }

    <pre><code class="line-numbers">## PKI管理模型

    ### PKI实体

    – 最终实体(End Entities,EE)

    最终实体就是subject字段所代表的主体。后面最终实体都用EE表示。

    – 证书颁发机构(Certification Authority,CA)

    CA是issuer字段所代表的主体,CA可以是第三方主体,也可以是与EE相同的主体,可以是离线的也可以是在线的。root CA是EE需要直接信任的CA。

    – 注册机构(Registration Authority,RA)

    许多环境需要独立于CA的注册机构。
    注册机构可能执行的功能因情况而异,但可能包括个人身份验证、令牌分发、撤销报告、名称分配、密钥生成、密钥对存档等。
    RA是可选的,当没有RA时CA完成RA的所有功能。

    RA本身也是一个EE,RA其实就是具有可以签名私钥(签名CSR)的经过认证的EE,CA把哪体EE识别为RA取决于具体实现。一个RA可以属于多个CA。

    ### PKI管理操作

    管理操作的流程图
    “`ascii
    +—+ cert. publish +————+ j
    | | <——————— | End Entity | <——-
    | C | g +————+ “out-of-band”
    | e | | ^ loading
    | r | | | initial
    | t | a | | b registration/
    | | | | certification
    | / | | | key pair recovery
    | | | | key pair update
    | C | | | certificate update
    | R | PKI “USERS” V | revocation request
    | L | ——————-+-+—–+-+——+-+——————-
    | | PKI MANAGEMENT | ^ | ^
    | | ENTITIES a | | b a | | b
    | R | V | | |
    | e | g +——+ d | |
    | p | <———— | RA | <—–+ | |
    | o | cert. | | —-+ | | |
    | s | publish +——+ c | | | |
    | i | | | | |
    | t | V | V |
    | o | g +————+ i
    | r | <————————| CA |——->
    | y | h +————+ “out-of-band”
    | | cert. publish | ^ publication
    | | CRL publish | |
    +—+ | | cross-certification
    e | | f cross-certificate
    | | update
    | |
    V |
    +——+
    | CA-2 |
    +——+

    PKI管理操作包括:

    1. CA建立

      生成自签名证书或者中间CA证书,生成初始CRL,生成证书序列号文件,生成证书数据库

    2. EE初始化

      导入CA证书,获取CA的其它信息

    3. Certification(创建新证书的各种操作)

      3.1. initial registration/certification

      生成密钥对,注册或生成自己的证书请求

      3.2. key pair update

      更新密钥对并颁发新的证书

      3.3. certificate update

      证书过期时如果环境没有任何其它的变化则会refreshed证书

      3.4. CA key pair update

      与EE一样,CA密钥对也需要进行更新,但是会使用不同的机制

      3.5. cross-certification request

      一个CA向另一个CA请求交叉证书

      3.6. cross-certificate update

      同普通证书update

    4. Certificate/CRL discovery operations

      后面具体讲

    5. Recovery operations

      主要是key pair recovery,如果EE丢失了自己的私钥并且CA备份了EE的私钥的情况下可以请求CA恢复私钥

    6. Revocation operations

      证书吊销

    7. PSE operations

      PSE是啥RFC4210中也没说,我想指的应该是发布证书的时候确保提供一个安全渠道。

    Assumptions and Restrictions

    rfc4210中是叫这个标题,我也不知道啥意思

    1. Initiation of Registration/Certification

      第一条PKI消息的产生意味着触发Initiation of Registration/Certification,这可以发生在任何地方,包括EE,RA,CA。

    2. End Entity Message Origin Authentication

      EE与RA或CA通信时需要经过身份认证,也可以不认证。本规范中是通过secret value(用于生成保护字段的MAC,同时用于初始化请求的身份验证,华为的文档中叫秘密值)和reference value(就是senderKID的referenceNum,华为的文档中叫参考值)来认证的,secret value和reference value由CA生成并通过带外途径发送给EE。

    3. Location of Key Generation

      密钥生成的位置等同于PKI消息中首次出现密钥的地方,这可以是EE,RA,CA。

    4. Confirmation of Successful Certification

      CA生成证书后,可以让EE明确接收或不接受证书。

    Mandatory Schemes

    1. Centralized Scheme

      即中心化方案

      • Initiation of Registration/Certification由CA完成
      • 不需要End Entity Message Origin Authentication
      • Location of Key Generation生成在CA
      • 不需要Confirmation of Successful Certification
    2. Basic Authenticated Scheme
      • Initiation of Registration/Certification由EE完成
      • 需要End Entity Message Origin Authentication
      • Location of Key Generation生成在EE
      • 需要Confirmation of Successful Certification

    Proof-of-Possession (POP) of Private Key

    EE持有的私钥,需要向CA/RA证明自己是对应公钥的私钥持有者,这包括用自己的私钥对证书请求进行签名,向CA/RA发送私钥,使用私钥加密一个值。对于Key Agreement Keys,例如DH密钥,可以通过生成一个共享密钥来证明。
    POP证明有很多种,包括包含私钥,直接法(质询响应),间接法(公钥加密证书),后面还有更多说明。

    Root CA Key Update

    更新root CA的密钥是一个比较麻烦的事,因为需要所有EE,RA都要同步处理。
    需要执行的操作包括:

    1. Generate a new key pair;

    2. Create a certificate containing the old CA public key signed with
      the new private key (the “old with new” certificate);

    3. Create a certificate containing the new CA public key signed with
      the old private key (the “new with old” certificate);

    4. Create a certificate containing the new CA public key signed with
      the new private key (the “new with new” certificate);

    5. Publish these new certificates via the repository and/or other
      means (perhaps using a CAKeyUpdAnn message);

    6. Export the new CA public key so that end entities may acquire it
      using the “out-of-band” mechanism (if required).

    The old CA private key is then no longer required. However, the old
    CA public key will remain in use for some time. The old CA public
    key is no longer required (other than for non-repudiation) when all
    end entities of this CA have securely acquired the new CA public key.
    The “old with new” certificate must have a validity period starting
    at the generation time of the old key pair and ending at the expiry
    date of the old public key.

    The “new with old” certificate must have a validity period starting
    at the generation time of the new key pair and ending at the time by
    which all end entities of this CA will securely possess the new CA
    public key (at the latest, the expiry date of the old public key).

    The “new with new” certificate must have a validity period starting
    at the generation time of the new key pair and ending at or before
    the time by which the CA will next update its key pair.

    数据结构

    总体PKI消息

        PKIMessage ::= SEQUENCE {
             header           PKIHeader,
             body             PKIBody,
             protection   [0] PKIProtection OPTIONAL,
             extraCerts   [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
                              OPTIONAL
        }
        PKIMessages ::= SEQUENCE SIZE (1..MAX) OF PKIMessage
    
    protection 就是消息的签名或者完整性验证
    extraCerts 如果颁发证书的CA不是rootCA,则需要一个证书链来验证证书的有效性,所以这就是新证书的证书链(如果有的话)。在证书请求中还可以用于包含当前用于签名验证的证书。Root CA Key Update消息中则用于发布证书。所以这个字段在不同场景下用途也不一样。
    

    PKI消息头

        PKIHeader ::= SEQUENCE {
            pvno                INTEGER     { cmp1999(1), cmp2000(2) },
            sender              GeneralName,
            recipient           GeneralName,
            messageTime     [0] GeneralizedTime         OPTIONAL,
            protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
            senderKID       [2] KeyIdentifier           OPTIONAL,
            recipKID        [3] KeyIdentifier           OPTIONAL,
            transactionID   [4] OCTET STRING            OPTIONAL,
            senderNonce     [5] OCTET STRING            OPTIONAL,
            recipNonce      [6] OCTET STRING            OPTIONAL,
            freeText        [7] PKIFreeText             OPTIONAL,
            generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
                                InfoTypeAndValue     OPTIONAL
        }
        PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
    

    pvno 就是cmp协议的版本号,对于rfc4210来说始终是2
    sender 发送者的DN名称
    recipient 接收者的DN名称
    messageTime 消息发送时间
    protectionAlg protection字段的算法标识符
    senderKID,recipKID DH算法的密钥标识符,有多对密钥时才需要,在初始化请求中senderKID就是用于身份认证的referenceNum(参考值)
    transactionID 事务ID,也就是会话ID,一般由发起会话者生成,后面保持不变
    senderNonce,recipNonce 每个报文生成一个随机数(为什么不用递增序列?),用于防重放攻击
    freeText 包含人类可读信息(可以由多个),回复消息时使用与第一个Text相同的语言。
    generalInfo 向对方发送附加的机器可处理信息,这是一个generalInfo类型的数组,一共定义了以下generalInfo扩展:

    • ImplicitConfirm
      implicitConfirm OBJECT IDENTIFIER ::= {id-it 13}
      ImplicitConfirmValue ::= NULL
      

      如果存在这个generalInfo扩展则不发送证书确认

    • ConfirmWaitTime

      confirmWaitTime OBJECT IDENTIFIER ::= {id-it 14}
      ConfirmWaitTimeValue ::= GeneralizedTime
      

      证书确认的超时时间,如果超时则撤销证书并删除会话。

    PKI消息体

            PKIBody ::= CHOICE {
              ir       [0]  CertReqMessages,       --Initialization Req
              ip       [1]  CertRepMessage,        --Initialization Resp
              cr       [2]  CertReqMessages,       --Certification Req
              cp       [3]  CertRepMessage,        --Certification Resp
              p10cr    [4]  CertificationRequest,  --PKCS #10 Cert.  Req.
              popdecc  [5]  POPODecKeyChallContent --pop Challenge
              popdecr  [6]  POPODecKeyRespContent, --pop Response
              kur      [7]  CertReqMessages,       --Key Update Request
              kup      [8]  CertRepMessage,        --Key Update Response
              krr      [9]  CertReqMessages,       --Key Recovery Req
              krp      [10] KeyRecRepContent,      --Key Recovery Resp
              rr       [11] RevReqContent,         --Revocation Request
              rp       [12] RevRepContent,         --Revocation Response
              ccr      [13] CertReqMessages,       --Cross-Cert.  Request
              ccp      [14] CertRepMessage,        --Cross-Cert.  Resp
              ckuann   [15] CAKeyUpdAnnContent,    --CA Key Update Ann.
              cann     [16] CertAnnContent,        --Certificate Ann.
              rann     [17] RevAnnContent,         --Revocation Ann.
              crlann   [18] CRLAnnContent,         --CRL Announcement
              pkiconf  [19] PKIConfirmContent,     --Confirmation
              nested   [20] NestedMessageContent,  --Nested Message
              genm     [21] GenMsgContent,         --General Message
              genp     [22] GenRepContent,         --General Response
              error    [23] ErrorMsgContent,       --Error Message
              certConf [24] CertConfirmContent,    --Certificate confirm
              pollReq  [25] PollReqContent,        --Polling request
              pollRep  [26] PollRepContent         --Polling response
              }
    
    

    一共27种报文,还是比较多的。
    具体描述在下在面。

    Common Data Structures

    在说明具本的PKIBody前要先说一下通用的数据结构

    • 发送证书

    当需要包含证书内容时使用CertTemplate语法,CA/RA可能修改证书请求的内容,EE也可以选择拒绝CA签置的证书(如果内容被修改)。

    • Encrypted Values

    通常是私钥和证书(接收新证书),需要使用EncryptedValue数据结构,要求双方事先有能解密秘密数据的密钥。

    • 状态码和故障信息

    状态码

            PKIStatus ::= INTEGER {
                accepted               (0),
                grantedWithMods        (1),
                rejection              (2),
                waiting                (3),
                revocationWarning      (4),
                revocationNotification (5),
                keyUpdateWarning       (6)
            }
    

    故障

            PKIFailureInfo ::= BIT STRING {
                badAlg              (0),
                badMessageCheck     (1),
                badRequest          (2),
                badTime             (3),
                badCertId           (4),
                badDataFormat       (5),
                wrongAuthority      (6),
                incorrectData       (7),
                missingTimeStamp    (8),
                badPOP              (9),
                certRevoked         (10),
                certConfirmed       (11),
                wrongIntegrity      (12),
                badRecipientNonce   (13),
                timeNotAvailable    (14),
                unacceptedPolicy    (15),
                unacceptedExtension (16),
                addInfoNotAvailable (17),
                badSenderNonce      (18),
                badCertTemplate     (19),
                signerNotTrusted    (20),
                transactionIdInUse  (21),
                unsupportedVersion  (22),
                notAuthorized       (23),
                systemUnavail       (24),
                systemFailure       (25),
                duplicateCertReq    (26)
            }
            PKIStatusInfo ::= SEQUENCE {
                status        PKIStatus,
                statusString  PKIFreeText     OPTIONAL,
                failInfo      PKIFailureInfo  OPTIONAL
            }
    
    • 证书标识

    用于标只特定的证书,使用CertId数据结构

    • root CA
    OOBCert ::= Certificate
    # or
    OOBCertHash ::= SEQUENCE {
        hashAlg     [0] AlgorithmIdentifier     OPTIONAL,
        certId      [1] CertId                  OPTIONAL,
        hashVal         BIT STRING
    }
    

    对于Certificat要求:

    • 证书是自签名的,即可以使用SubjectPublicKeyInfo中的公钥验证签名
    • subject和issuer相同
    • 如果subject为空则要求SubjectAltName和issuerAltNames相同
    • key identifiers for subject and issuer相同

    OOBCertHash用途是通过带外方式获取root CA时对root CA进行验证。

    • Archive Options

    请求者希望PKI使用PKIArchiveOptions结构存档私钥

    • Publication Information

    请求者希望PKI通过PKIPublicationInfo结构发布证书

    • Proof-of-Possession Structures

      如果请求的是一个签名证书,私钥的所有权证明是通过POPOSigningKey结构完成的。

      参考附录 C and [CRMF] for POPOSigningKey 语法,

          POPOSigningKey ::= SEQUENCE {
              poposkInput           [0] POPOSigningKeyInput OPTIONAL,
              algorithmIdentifier   AlgorithmIdentifier,
              signature             BIT STRING
              #这个签名是用私钥对poposkInput的DER编码的签名,如果EE能用公钥验证这个签名就完成了私钥所有权证明
          }
          POPOSigningKeyInput ::= SEQUENCE {
              authInfo            CHOICE {
                  sender              [0] GeneralName,
                  publicKeyMAC        PKMACValue
              },
              publicKey           SubjectPublicKeyInfo
          }
      

      另一方面, 如果请求的是一个加密证书, 那么私钥的所有权证明可以用下面三种方法中的一个(包含私钥,直接法,间接法)

    • Inclusion of the Private Key

      在CertRequest请求的POPOPrivKey的thisMessage,或者通过PKIArchiveOptions字段包含私钥,这取决于是否需要私钥存档

      POPOPrivKey ::= CHOICE {
          thisMessage       [0] BIT STRING,
      -- **********
      -- * the type of "thisMessage" is given as BIT STRING in
      -- * [CRMF]; it should be "EncryptedValue" (in accordance
      -- * with Section 5.2.2, "Encrypted Values", of this specification).
      -- * Therefore, this document makes the behavioral clarification
      -- * of specifying that the contents of "thisMessage" MUST be encoded
      -- * as an EncryptedValue and then wrapped in a BIT STRING.  This
      -- * allows the necessary conveyance and protection of the
      -- * private key while maintaining bits-on-the-wire compatibility
      -- * with [CRMF].
      -- **********
      subsequentMessage [1] SubsequentMessage,
      dhMAC             [2] BIT STRING }
      
    • Indirect Method

      返回公钥加密的证书,只有用EE的私钥才能解密。

    • Challenge-Response Protocol(direct method)

      通过Challenge-Response Protocol证明EE私钥的POP

    • PoP选项总结

      下面列出了代表各种POP技术的选项. Using “SK” for “signing key”, “EK” for “encryption key”,and “KAK” for “key agreement key”, 总结如下:

      RAVerified;
      SKPOP;
      EKPOPThisMessage;
      KAKPOPThisMessage;
      KAKPOPThisMessageDHMAC;
      EKPOPEncryptedCert;
      KAKPOPEncryptedCert;
      EKPOPChallengeResp; and
      KAKPOPChallengeResp.
      

      考虑到这一系列选项,自然会问EE如何知道CA/RA支持什么选项/技术(即,在请求证书时可以使用哪些选项)。以下指南应该为EE实现者澄清这种情况。

      • RAVerified

        这是RA向CA请求是用的,EE不需要考虑

      • SKPOP

        如果EE有一个签名密钥对,则这是唯一可用选项

      • EKPOPThisMessage and KAKPOPThisMessage

        如果决定向CA/RA公开私钥,则只有这里的方法可以做到,根据密钥类型选择EKPOPThisMessage 还是 KAKPOPThisMessage

      • KAKPOPThisMessageDHMAC

        仅当CA有可用于此目的的DH证书,以及EE已经有此证书的副本时,EE才能使用此方法。如果这两个条件都成立,那么这种技术就得到了明确的支持。

      • EKPOPEncryptedCert, KAKPOPEncryptedCert, EKPOPChallengeResp, KAKPOPChallengeResp

        EE在请求消息中选择其中一个(在subsequentMessage字段中),具体取决于偏好和密钥对类型。EE在此处没有做POP;它只是向CA/RA指示要使用哪种方法。因此,如果CA/RA回复“badPOP”错误,则EE可以使用在后续消息中选择的其他POP方法重新请求。但是,请注意,本规范鼓励使用EncryptedCert选项,并且还指出,当涉及RA并进行POP验证时,通常会使用质询响应。间接方法需要发送的消息更少,也比较简单是EE尽可能使用这种方法,如果是向RA提交POP证明则会使用直接方法(质询响应)

    特定操作的数据结构

    一共定义了27个操作类型,怪不得CMP是最复杂的证书协议

    • Initialization Request

      一个Initialization请求包含CertReqMessages数据结构作为PKI Body,该数据结构指定要请求的证书(CRMF格式(RFC4211),类似于PKCS#10),通常会包含SubjectPublicKeyInfo、KeyId和Validity字段。此消息用于首次初始化PKI实体时。
      因为是首次请求证书需要带外方式获取身份验证信息,使用MSG_MAC_ALG进行身份验证,MAC信息是用共享的Secret加了盐的。senderKID就是参考值。
      一个请求可以包含多个证书,证书模板(要请求的证书)放在CertTemplate字段中。

      CertReqMessages在Rfc4211中定义,很复杂,以下是ASN.1代码:

      -- Core definitions for this module
      
      CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg
      
      CertReqMsg ::= SEQUENCE {
      certReq   CertRequest,
      popo       ProofOfPossession  OPTIONAL,
      -- content depends upon key type
      regInfo   SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue OPTIONAL }
      
      CertRequest ::= SEQUENCE {
      certReqId     INTEGER,          -- ID for matching request and reply
      certTemplate  CertTemplate,  -- Selected fields of cert to be issued
      controls      Controls OPTIONAL }   -- Attributes affecting issuance
      
      CertTemplate ::= SEQUENCE {
      version      [0] Version               OPTIONAL,
      serialNumber [1] INTEGER               OPTIONAL,
      signingAlg   [2] AlgorithmIdentifier   OPTIONAL,
      issuer       [3] Name                  OPTIONAL,
      validity     [4] OptionalValidity      OPTIONAL,
      subject      [5] Name                  OPTIONAL,
      publicKey    [6] SubjectPublicKeyInfo  OPTIONAL,
      issuerUID    [7] UniqueIdentifier      OPTIONAL,
      subjectUID   [8] UniqueIdentifier      OPTIONAL,
      extensions   [9] Extensions            OPTIONAL }
      
      OptionalValidity ::= SEQUENCE {
      notBefore  [0] Time OPTIONAL,
      notAfter   [1] Time OPTIONAL } -- at least one MUST be present
      
      Controls  ::= SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue
      AttributeTypeAndValue ::= SEQUENCE {
      type         OBJECT IDENTIFIER,
      value        ANY DEFINED BY type }
      
      ProofOfPossession ::= CHOICE {
      raVerified        [0] NULL,
      -- used if the RA has already verified that the requester is in
      -- possession of the private key
      signature         [1] POPOSigningKey,
      keyEncipherment   [2] POPOPrivKey,
      keyAgreement      [3] POPOPrivKey }
      
      POPOSigningKey ::= SEQUENCE {
      poposkInput           [0] POPOSigningKeyInput OPTIONAL,
      algorithmIdentifier   AlgorithmIdentifier,
      signature             BIT STRING }
      -- The signature (using "algorithmIdentifier") is on the
      -- DER-encoded value of poposkInput.  NOTE: If the CertReqMsg
      -- certReq CertTemplate contains the subject and publicKey values,
      -- then poposkInput MUST be omitted and the signature MUST be
      -- computed over the DER-encoded value of CertReqMsg certReq.  If
      -- the CertReqMsg certReq CertTemplate does not contain both the
      -- public key and subject values (i.e., if it contains only one
      -- of these, or neither), then poposkInput MUST be present and
      -- MUST be signed.
      
      
      POPOSigningKeyInput ::= SEQUENCE {
      authInfo            CHOICE {
          sender              [0] GeneralName,
          -- used only if an authenticated identity has been
          -- established for the sender (e.g., a DN from a
          -- previously-issued and currently-valid certificate)
          publicKeyMAC        PKMACValue },
          -- used if no authenticated GeneralName currently exists for
          -- the sender; publicKeyMAC contains a password-based MAC
          -- on the DER-encoded value of publicKey
      publicKey           SubjectPublicKeyInfo }  -- from CertTemplate
      
      PKMACValue ::= SEQUENCE {
      algId  AlgorithmIdentifier,
      -- algorithm value shall be PasswordBasedMac {1 2 840 113533 7 66 13}
      -- parameter value is PBMParameter
      value  BIT STRING }
      
      PBMParameter ::= SEQUENCE {
      salt                OCTET STRING,
      owf                 AlgorithmIdentifier,
      -- AlgId for a One-Way Function (SHA-1 recommended)
      iterationCount      INTEGER,
      -- number of times the OWF is applied
      mac                 AlgorithmIdentifier
      -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11],
      }   -- or HMAC [HMAC, RFC2202])
      
      POPOPrivKey ::= CHOICE {
      thisMessage       [0] BIT STRING,         -- Deprecated
      -- possession is proven in this message (which contains the private
      -- key itself (encrypted for the CA))
      subsequentMessage [1] SubsequentMessage,
      -- possession will be proven in a subsequent message
      dhMAC             [2] BIT STRING,         -- Deprecated
      agreeMAC          [3] PKMACValue,
      encryptedKey      [4] EnvelopedData }
      
      -- for keyAgreement (only), possession is proven in this message
      -- (which contains a MAC (over the DER-encoded value of the
      -- certReq parameter in CertReqMsg, which MUST include both subject
      -- and publicKey) based on a key derived from the end entity's
      -- private DH key and the CA's public DH key);
      
      SubsequentMessage ::= INTEGER {
      encrCert (0),
      -- requests that resulting certificate be encrypted for the
      -- end entity (following which, POP will be proven in a
      -- confirmation message)
      challengeResp (1) }
      -- requests that CA engage in challenge-response exchange with
      -- end entity in order to prove private key possession
      
      -- Object identifier assignments --
      
      -- Registration Controls in CRMF
      id-regCtrl OBJECT IDENTIFIER ::= { id-pkip 1 }
      
      
      id-regCtrl-regToken OBJECT IDENTIFIER ::= { id-regCtrl 1 }
      --with syntax:
      RegToken ::= UTF8String
      
      id-regCtrl-authenticator OBJECT IDENTIFIER ::= { id-regCtrl 2 }
      --with syntax:
      Authenticator ::= UTF8String
      
      id-regCtrl-pkiPublicationInfo OBJECT IDENTIFIER ::= { id-regCtrl 3 }
      --with syntax:
      
      PKIPublicationInfo ::= SEQUENCE {
      action     INTEGER {
                  dontPublish (0),
                  pleasePublish (1) },
      pubInfos  SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL }
      -- pubInfos MUST NOT be present if action is "dontPublish"
      -- (if action is "pleasePublish" and pubInfos is omitted,
      -- "dontCare" is assumed)
      
      SinglePubInfo ::= SEQUENCE {
      pubMethod    INTEGER {
          dontCare    (0),
          x500        (1),
          web         (2),
          ldap        (3) },
      pubLocation  GeneralName OPTIONAL }
      
      id-regCtrl-pkiArchiveOptions     OBJECT IDENTIFIER ::= { id-regCtrl 4 }
      --with syntax:
      PKIArchiveOptions ::= CHOICE {
      encryptedPrivKey     [0] EncryptedKey,
      -- the actual value of the private key
      keyGenParameters     [1] KeyGenParameters,
      -- parameters that allow the private key to be re-generated
      archiveRemGenPrivKey [2] BOOLEAN }
      -- set to TRUE if sender wishes receiver to archive the private
      -- key of a key pair that the receiver generates in response to
      -- this request; set to FALSE if no archival is desired.
      
      EncryptedKey ::= CHOICE {
      encryptedValue        EncryptedValue,   -- Deprecated
      envelopedData     [0] EnvelopedData }
      -- The encrypted private key MUST be placed in the envelopedData
      -- encryptedContentInfo encryptedContent OCTET STRING.
      
      EncryptedValue ::= SEQUENCE {
      intendedAlg   [0] AlgorithmIdentifier  OPTIONAL,
      -- the intended algorithm for which the value will be used
      symmAlg       [1] AlgorithmIdentifier  OPTIONAL,
      -- the symmetric algorithm used to encrypt the value
      encSymmKey    [2] BIT STRING           OPTIONAL,
      -- the (encrypted) symmetric key used to encrypt the value
      keyAlg        [3] AlgorithmIdentifier  OPTIONAL,
      -- algorithm used to encrypt the symmetric key
      valueHint     [4] OCTET STRING         OPTIONAL,
      -- a brief description or identifier of the encValue content
      -- (may be meaningful only to the sending entity, and used only
      -- if EncryptedValue might be re-examined by the sending entity
      -- in the future)
      encValue       BIT STRING }
      -- the encrypted value itself
      -- When EncryptedValue is used to carry a private key (as opposed to
      -- a certificate), implementations MUST support the encValue field
      -- containing an encrypted PrivateKeyInfo as defined in [PKCS11],
      -- section 12.11.  If encValue contains some other format/encoding
      -- for the private key, the first octet of valueHint MAY be used
      -- to indicate the format/encoding (but note that the possible values
      -- of this octet are not specified at this time).  In all cases, the
      -- intendedAlg field MUST be used to indicate at least the OID of
      -- the intended algorithm of the private key, unless this information
      -- is known a priori to both sender and receiver by some other means.
      
      KeyGenParameters ::= OCTET STRING
      
      id-regCtrl-oldCertID          OBJECT IDENTIFIER ::= { id-regCtrl 5 }
      --with syntax:
      OldCertId ::= CertId
      
      CertId ::= SEQUENCE {
      issuer           GeneralName,
      serialNumber     INTEGER }
      
      id-regCtrl-protocolEncrKey    OBJECT IDENTIFIER ::= { id-regCtrl 6 }
      --with syntax:
      ProtocolEncrKey ::= SubjectPublicKeyInfo
      
      -- Registration Info in CRMF
      id-regInfo OBJECT IDENTIFIER ::= { id-pkip 2 }
      
      id-regInfo-utf8Pairs    OBJECT IDENTIFIER ::= { id-regInfo 1 }
      --with syntax
      UTF8Pairs ::= UTF8String
      
      
      id-regInfo-certReq       OBJECT IDENTIFIER ::= { id-regInfo 2 }
      --with syntax
      CertReq ::= CertRequest
      
      -- id-ct-encKeyWithID is a new content type used for CMS objects.
      -- it contains both a private key and an identifier for key escrow
      -- agents to check against recovery requestors.
      
      id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21}
      
      EncKeyWithID ::= SEQUENCE {
      privateKey           PrivateKeyInfo,
      identifier CHOICE {
          string             UTF8String,
          generalName        GeneralName
      } OPTIONAL
      }
      
      PrivateKeyInfo ::= SEQUENCE {
      version                   INTEGER,
      privateKeyAlgorithm       AlgorithmIdentifier,
      privateKey                OCTET STRING,
      attributes                [0] IMPLICIT Attributes OPTIONAL
      }
      
      Attributes ::= SET OF Attribute
      
    • Initialization Response

      初始化请求的响应,返回请求的证书
      CertRepMessage数据结构作为PKIBody,该数据结构为每个请求的证书提供一个PKIStatusInfo字段、一个主题证书,可能还有一个私钥(通常使用会话密钥加密,会话密钥本身使用ProtocolEncrey加密。
      CertRepMessage的asn.1代码

          CertRepMessage ::= SEQUENCE {
              caPubs       [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
                              OPTIONAL,
              response         SEQUENCE OF CertResponse
          }
      
          CertResponse ::= SEQUENCE {
              certReqId           INTEGER,
              -- to match this response with corresponding request (a value
              -- of -1 is to be used if certReqId is not specified in the
              -- corresponding request)
              status              PKIStatusInfo,
              certifiedKeyPair    CertifiedKeyPair    OPTIONAL,
              rspInfo             OCTET STRING        OPTIONAL
              -- analogous to the id-regInfo-utf8Pairs string defined
              -- for regInfo in CertReqMsg [CRMF]
          }
      
          CertifiedKeyPair ::= SEQUENCE {
              certOrEncCert       CertOrEncCert,
              privateKey      [0] EncryptedValue      OPTIONAL,
              -- see [CRMF] for comment on encoding
              publicationInfo [1] PKIPublicationInfo  OPTIONAL
          }
      
          CertOrEncCert ::= CHOICE {
              certificate     [0] CMPCertificate,
              encryptedCert   [1] EncryptedValue
          }
      
          KeyRecRepContent ::= SEQUENCE {
              status                  PKIStatusInfo,
              newSigCert          [0] CMPCertificate OPTIONAL,
              caCerts             [1] SEQUENCE SIZE (1..MAX) OF
                                                  CMPCertificate OPTIONAL,
              keyPairHist         [2] SEQUENCE SIZE (1..MAX) OF
                                                  CertifiedKeyPair OPTIONAL
          }
      
          RevReqContent ::= SEQUENCE OF RevDetails
      
          RevDetails ::= SEQUENCE {
              certDetails         CertTemplate,
              -- allows requester to specify as much as they can about
              -- the cert. for which revocation is requested
              -- (e.g., for cases in which serialNumber is not available)
              crlEntryDetails     Extensions       OPTIONAL
              -- requested crlEntryExtensions
          }
      
          RevRepContent ::= SEQUENCE {
              status       SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
              -- in same order as was sent in RevReqContent
              revCerts [0] SEQUENCE SIZE (1..MAX) OF CertId
                                                  OPTIONAL,
              -- IDs for which revocation was requested
              -- (same order as status)
              crls     [1] SEQUENCE SIZE (1..MAX) OF CertificateList
                                                  OPTIONAL
              -- the resulting CRLs (there may be more than one)
          }
      
          CAKeyUpdAnnContent ::= SEQUENCE {
              oldWithNew   CMPCertificate, -- old pub signed with new priv
              newWithOld   CMPCertificate, -- new pub signed with old priv
              newWithNew   CMPCertificate  -- new pub signed with new priv
          }
      
          CertAnnContent ::= CMPCertificate
      
          RevAnnContent ::= SEQUENCE {
              status              PKIStatus,
              certId              CertId,
              willBeRevokedAt     GeneralizedTime,
              badSinceDate        GeneralizedTime,
              crlDetails          Extensions  OPTIONAL
              -- extra CRL details (e.g., crl number, reason, location, etc.)
          }
      
          CRLAnnContent ::= SEQUENCE OF CertificateList
      
          CertConfirmContent ::= SEQUENCE OF CertStatus
      
          CertStatus ::= SEQUENCE {
              certHash    OCTET STRING,
              -- the hash of the certificate, using the same hash algorithm
              -- as is used to create and verify the certificate signature
              certReqId   INTEGER,
              -- to match this confirmation with the corresponding req/rep
              statusInfo  PKIStatusInfo OPTIONAL
          }
          CMPCertificate ::= CHOICE {
          x509v3PKCert        Certificate
          }
      
    • Certification Request(证书请求)

      现有PKI EE获得其它证书(用已有证书提供身份验证),报文格式同Initialization Request。
      PKI主体可以是CertificationRequest(此结构由[PKCS10]中给出的ASN.1结构CertificationRequest完全指定,用于支持PKCS #10证书请求)。当需要与遗留系统进行互操作时,签名密钥对的证书请求可能需要此结构,但如果不是绝对必要,强烈建议不要使用此结构(为什么不建议呢?)。

    • Certification Response

      报文格式同Initialization Response

    • Key Update Request Content

      仍然使用CertReqMessages PKI Body,但是要包括SubjectPublicKeyInfo、KeyId和Validity字段,此消息用于请求对现有(未吊销和未过期)证书的更新(因此,有时称为“Certificate Update”操作)。更新是包含新subject公钥或当前subject公钥的替换证书(尽管后一种做法可能不适用于某些环境)。

    • Key Update Response Content

      报文格式同Initialization Response

    • Key Recovery Request Content

      报文格式同Initialization Request,但SubjectPublicKeyInfo和KeyId是必选字段可用于提供需要证书的签名公钥

    • Key Recovery Response Content

      使用以下结构作为Key Recovery Request Content的响应

          KeyRecRepContent ::= SEQUENCE {
              status          PKIStatusInfo,
              newSigCert  [0] Certificate                   OPTIONAL,
              caCerts     [1] SEQUENCE SIZE (1..MAX) OF
                                          Certificate      OPTIONAL,
              keyPairHist [2] SEQUENCE SIZE (1..MAX) OF
                                          CertifiedKeyPair OPTIONAL
          }
      
    • Revocation Request Content

      请求吊销证书
      PKI Body结构:

          RevReqContent ::= SEQUENCE OF RevDetails
      
      
          RevReqContent ::= SEQUENCE OF RevDetails
      
      
          RevDetails ::= SEQUENCE {
              certDetails         CertTemplate,
              crlEntryDetails     Extensions       OPTIONAL
          }
      
    • Revocation Response Content

      撤销响应是对上述消息的响应。如果生成,则发送给撤销请求者。(可向请求撤销的证书主体发送单独的撤销公告消息。)

          RevRepContent ::= SEQUENCE {
              status        SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
              revCerts  [0] SEQUENCE SIZE (1..MAX) OF CertId OPTIONAL,
              crls      [1] SEQUENCE SIZE (1..MAX) OF CertificateList
                          OPTIONAL
          }
      
    • Cross Certification Request Content

      请求交叉认证证书
      交叉认证请求使用与普通认证请求相同的语法(CertReqMessages),但有一个限制,即密钥对必须由请求CA生成,并且私钥不得发送到响应CA。下级CA也可以使用此请求来获取由父CA签名的证书。

    • Cross Certification Response Content

      交叉认证响应使用与正常认证响应相同的语法(CertRepMessage),但限制不能发送加密的私钥。

    • CA Key Update Announcement Content

      当CA更新其自己的密钥对时,可以使用以下数据结构来宣布此事件。

        CAKeyUpdAnnContent ::= SEQUENCE {
           oldWithNew         Certificate,
           newWithOld         Certificate,
           newWithNew         Certificate
        }
    
    • Certificate Announcement

      此结构可用于宣布证书的存在。 请注意,此消息旨在用于没有其它证书发布方法的情况;例如,如果X.500(LDAP)是发布证书的方法,则不打算使用该方法。

      CertAnnContent ::= Certificate
      
    • Revocation Announcement

      当CA已撤销或即将撤销特定证书时,它可能会发布此事件的公告。

              RevAnnContent ::= SEQUENCE {
                  status              PKIStatus,
                  certId              CertId,
                  willBeRevokedAt     GeneralizedTime,
                  badSinceDate        GeneralizedTime,
                  crlDetails          Extensions  OPTIONAL
              }
      

      CA可以使用此类公告警告(或通知)主体其证书即将(或已)被吊销。这通常用于撤销请求并非来自相关主体的情况。
      willBeRevokedAt字段包含将新条目添加到相关CRL的时间。

      • CRL Announcement
        当CA发布新的CRL(或一组CRL)时,可以使用以下数据结构来宣布此事件。
      CRLAnnContent ::= SEQUENCE OF CertificateList
      
    • PKI Confirmation Content

      此数据结构在协议交换中用作最终PKI消息。它的内容在所有情况下都是相同的——实际上没有内容,因为PKI头包含所有必需的信息。

      PKIConfirmContent ::= NULL
      

      不建议将此消息用于证书确认;应改用certConf。在收到证书响应的PKIConfirm后,接收方可以将其视Certificate Confirmation Content,并接受所有证书。

    • Certificate Confirmation Content

      客户端使用此数据结构向CA/RA发送确认以接受或拒绝证书。

          CertConfirmContent ::= SEQUENCE OF CertStatus
      
          CertStatus ::= SEQUENCE {
          certHash    OCTET STRING,
          certReqId   INTEGER,
          statusInfo  PKIStatusInfo OPTIONAL
          }
      

      对于任何特定的CertStatus,省略statusInfo字段表示接受指定的证书。或者,可以在statusInfo字段中提供明确的状态详细信息(关于接受或拒绝),可能用于CA/RA的审计目的。
      在CertConfirmContent中,省略与前一响应消息中提供的证书对应的CertStatus结构表示拒绝证书。因此,空CertConfirmContent(零长度序列)可用于指示拒绝所有提供的证书。有关占有证明的certHash字段的讨论,请参见第5.2.8节第(2)项。

    • PKI General Message Content

          InfoTypeAndValue ::= SEQUENCE {
              infoType               OBJECT IDENTIFIER,
              infoValue              ANY DEFINED BY infoType  OPTIONAL
          }
          -- where {id-it} = {id-pkix 4} = {1 3 6 1 5 5 7 4}
          GenMsgContent ::= SEQUENCE OF InfoTypeAndValue
      

      没有归类的估计都放这了吧,这部分又包含了13种报文结构

      • CA Protocol Encryption Certificate

        用于EE向CA获取证书用于保护CMP会话

        GenMsg:    {id-it 1}, < absent >
        GenRep:    {id-it 1}, Certificate | < absent >
        

        这里面的absent应该表示的是只有表示infoType的oid,没有infoValue(猜测)’

      • Signing Key Pair Types

        获取CA支持的签名算法

        GenMsg:    {id-it 2}, < absent >
        GenRep:    {id-it 2}, SEQUENCE SIZE (1..MAX) OF
                AlgorithmIdentifier
        
      • Encryption/Key Agreement Key Pair Types

        获取CA的加密或KAK算法列表

        GenMsg:    {id-it 3}, < absent >
        GenRep:    {id-it 3}, SEQUENCE SIZE (1..MAX) OF
                                AlgorithmIdentifier
        
      • Preferred Symmetric Algorithm

        获取CA的首选对称加密算法

        GenMsg:    {id-it 4}, < absent >
        GenRep:    {id-it 4}, AlgorithmIdentifier
        
      • Updated CA Key Pair
        CA可用此消息宣布CA密钥对更新

        GenMsg:    {id-it 5}, CAKeyUpdAnnContent
        
      • CRL
        EE用此报文获取最新的CRL

        GenMsg:    {id-it 6}, < absent >
        GenRep:    {id-it 6}, CertificateList
        
      • Unsupported Object Identifiers

        服务器使用它从客户端提交的列表中返回它不识别或不支持的对象标识符列表。
        GenRep: {id-it 7}, SEQUENCE SIZE (1..MAX) OF OBJECT IDENTIFIER

      • Key Pair Parameters

        这可由EE用于请求域参数以用于生成特定公钥算法的密钥对。例如,它可以用于请求适当的P、Q和G以生成DH/DSA密钥,或者请求一组众所周知的椭圆曲线。

        GenMsg:    {id-it 10}, OBJECT IDENTIFIER -- (Algorithm object-id)
        GenRep:    {id-it 11}, AlgorithmIdentifier | < absent >
        

        GenRep中缺少infoValue表示不支持GenMsg中指定的算法。
        EEs必须确保参数是可接受的,并且GenRep消息经过身份验证(以避免替代攻击)。
        跟openssl genpkey的-genparam选项是不是有点类似

      • Revocation Passphrase

        这可由EE用于向CA/RA发送密码短语,以便认证稍后的撤销请求(在适当的签名私钥不再可用于认证请求的情况下)。有关此机制使用的更多详细信息,请参见附录B。

        GenMsg:    {id-it 12}, EncryptedValue
        GenRep:    {id-it 12}, < absent >
        
      • ImplicitConfirm

        不发送确认消息,这个前面通用部分已经说过

      • ConfirmWaitTime

        确认超时时间,前面通用部分已经说过

      • Original PKIMessage

        RA如果修改了EE的请求,再向CA发关请求时携带的原始PKIMessage(EE向RA发送消息)

      • Supported Language Tags

        这可用于确定在后续消息中使用的适当语言标记。发送方发送其支持的语言列表(按顺序,从最优先到最不优先);接收者返回它想要使用的那个。(注意:每个UTF8String必须包含一个语言标记。)如果不支持任何提供的标记,则必须返回错误。

        GenMsg:    {id-it 16}, SEQUENCE SIZE (1..MAX) OF UTF8String
        GenRep:    {id-it 16}, SEQUENCE SIZE (1) OF UTF8String
        
    • PKI General Response Content

      对General Message的响应

          InfoTypeAndValue ::= SEQUENCE {
              infoType               OBJECT IDENTIFIER,
              infoValue              ANY DEFINED BY infoType  OPTIONAL
          }
          -- where {id-it} = {id-pkix 4} = {1 3 6 1 5 5 7 4}
          GenMsgContent ::= SEQUENCE OF InfoTypeAndValue
      
    • Error Message Content
      EE、CA或RA可以使用此数据结构来传递错误信息

          ErrorMsgContent ::= SEQUENCE {
              pKIStatusInfo          PKIStatusInfo,
              errorCode              INTEGER           OPTIONAL,
              errorDetails           PKIFreeText       OPTIONAL
          }
      

      此消息可在PKI交易期间的任何时间生成。如果客户端发送此请求,服务器必须使用PKIConfirm响应进行响应,如果标头的任何部分无效,则必须使用另一个ErrorMsg进行响应。双方必须将此消息视为会话的结束(如果会话正在进行)。
      如果需要对消息进行保护,则客户端必须使用与Initialization Request相同的技术(即签名或MAC)对其进行保护。CA必须始终使用签名密钥对其进行签名。

    • Polling Request and Response
      这对消息用于处理客户端需要轮询服务器以确定未完成的ir、cr或kur会话的状态(即,当收到“waiting”PKIStatus时)的场景。

          PollReqContent ::= SEQUENCE OF SEQUENCE {
              certReqId    INTEGER }
      
          PollRepContent ::= SEQUENCE OF SEQUENCE {
              certReqId    INTEGER,
              checkAfter   INTEGER,  -- time in seconds
              reason       PKIFreeText OPTIONAL }
      

      以下子句描述何时使用轮询消息以及如何使用它们。假定在事务期间可以发送多个certConf消息。对于包含已颁发证书的CertStatus的每个ip、cp或kup,将发送一个响应。

      1. 如果EE收到对ip、cp或kup消息的响应,将为所有已颁发的证书发送certConf,并在确认之后为所有待定证书发送pollReq。
      2. 如果CA收到pollReq,如果一个或多个挂起证书就绪,CA/RA将返回ip、cp或kup的响应;否则,它将返回一个pollRep。
      3. 如果EE收到一个pollRep,它将在发送另一个pollReq之前等待至少与checkAfter值相同的时间。
      4. 如果在pollReq响应期间接收到ip、cp或kup,会按initial response相同的方法处理
                            START
                                |
                                v
                            Send ir
                                | ip
                                v
                            Check status
                            of returned <------------------------+
                            certs                             |
                                |                               |
        

        +————————>|<——————+ |
        | | | |
        | (issued) v (waiting) | |
        Add to <----------- Check CertResponse ------> Add to |
        conf list for each certificate pending list |
        / |
        / |
        (conf list) / (empty conf list) |
        / ip |
        / +—————-+
        (empty pending list) / | pRep
        END <---- Send certConf Send pReq------------>Wait
        | ^ ^ |
        | | | |
        +—————–+ +—————+
        (pending list)

      在以下交互中,EE在一个请求中注册两个证书。

      Step  End Entity                       PKI
      --------------------------------------------------------------------
      1   Format ir
      2                    -> ir      ->
      3                                    Handle ir
      4                                    Manual intervention is
                                          required for both certs.
      5                    <- ip      <-
      6   Process ip
      7   Format pReq
      8                    -> pReq     ->
      9                                    Check status of cert requests
      10                                   Certificates not ready
      11                                   Format pRep
      12                   <- pRep     <-
      13  Wait
      14  Format pReq
      15                   -> pReq     ->
      16                                   Check status of cert requests
      17                                   One certificate is ready
      18                                   Format ip
      19                   <- ip       <-
      20  Handle ip
      21  Format certConf
      22                   -> certConf ->
      23                                   Handle certConf
      24                                   Format ack
      25                   <- pkiConf   <-
      26  Format pReq
      27                   -> pReq     ->
      28                                   Check status of certificate
      29                                   Certificate is ready
      30                                   Format ip
      31                   <- ip       <-
      31  Handle ip
      32  Format certConf
      33                   -> certConf ->
      34                                   Handle certConf
      35                                   Format ack
      36                   <- pkiConf  <-
      

    强制性的PKI功能

    这些功能是EE,RA,CA必须实现的

    • Root CA初始化

      Root CA证书必须是自签名证书,为了支持EE通过带外方式获取Root CA证书还需要生成证书指纺,用OOBCertHash结构表示

    • Root CA密钥更新

      CA密钥(与所有其他密钥一样)具有有限的生存期,必须定期更新。CA可颁发证书NewWithNew、NewWithOld和OldWithNew(见第4.4.1节),以帮助持有当前自签名CA证书(OldWithOld)的现有终端实体安全地过渡到新自签名CA证书(NewWithNew),并帮助持有NewWithNew的新终端实体安全地获取OldWithOld,以验证现有数据。

    • 下级CA(中间CA)的初始化

      从PKI管理协议的角度来看,下级CA的初始化与终端实体的初始化相同。唯一的区别是下级CA还必须生成初始吊销列表.

    • CRL生成

      新成立的CA在颁发任何证书之前必须生成每个 CRL 的“空”版本,这些版本将定期生成。

    • PKI信息请求

      当PKI实体(CA、RA或EE)希望获取有关CA当前状态的信息时,它可以向该CA发送获取此类信息的请求。请求是通过一般消息中的PKI General Message Content消息实现的,响应是通过PKI General Response Content。

    • 交叉认证

      请求者CA是将成为交叉证书subject的CA;响应者CA将成为交叉证书的issuer。

    • EE初始化

      包括获取PKI信息(Root CA证书和其它信息),和Root CA的带外验证(指纹)

    • 证书请求(为什么不是初始化请求)

      已初始化的EE可随时(出于任何目的)请求额外的证书。此请求将使用证书请求(cr)消息发出。如果EE已经拥有签名密钥对(具有相应的验签证书),则该cr消息通常将受到EE数字签名的保护。CA在CertRepMessage中返回新证书(如果请求成功)。

    • 密钥更新

      当密钥对到期时,相关EE可请求密钥更新;也就是说,它可以请求CA为新密钥对颁发新证书(或者,在某些情况下,为同一密钥对颁发新证书)。使用密钥更新请求(kur)消息发出请求(在某些环境中称为“Certificate Update”操作)。如果EE已经拥有签名密钥对(具有相应的验证证书),则该消息通常将受到EE数字签名的保护。CA在密钥更新响应(kup)消息中返回新证书(如果请求成功),该消息在语法上与CertRepMessage相同。

    Views: 17