1#
2# Certificate Management Protocol structures as per RFC4210
3#
4# Based on Alex Railean's work
5#
6from pyasn1.type import tag,namedtype,namedval,univ,constraint,char,useful
7from pyasn1_modules import rfc2459, rfc2511, rfc2314
8
9MAX = 64
10
11class KeyIdentifier(univ.OctetString): pass
12
13class CMPCertificate(rfc2459.Certificate): pass
14
15class OOBCert(CMPCertificate): pass
16
17class CertAnnContent(CMPCertificate): pass
18
19class PKIFreeText(univ.SequenceOf):
20    """
21    PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
22    """
23    componentType = char.UTF8String()
24    subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX)
25
26class PollRepContent(univ.SequenceOf):
27    """
28         PollRepContent ::= SEQUENCE OF SEQUENCE {
29         certReqId              INTEGER,
30         checkAfter             INTEGER,  -- time in seconds
31         reason                 PKIFreeText OPTIONAL
32     }
33    """
34    class CertReq(univ.Sequence):
35        componentType = namedtype.NamedTypes(
36            namedtype.NamedType('certReqId', univ.Integer()),
37            namedtype.NamedType('checkAfter', univ.Integer()),
38            namedtype.OptionalNamedType('reason', PKIFreeText())
39        )
40    componentType = CertReq()
41
42class PollReqContent(univ.SequenceOf):
43    """
44         PollReqContent ::= SEQUENCE OF SEQUENCE {
45         certReqId              INTEGER
46     }
47
48    """
49    class CertReq(univ.Sequence):
50        componentType = namedtype.NamedTypes(
51            namedtype.NamedType('certReqId', univ.Integer())
52        )
53    componentType = CertReq()
54
55class InfoTypeAndValue(univ.Sequence):
56    """
57    InfoTypeAndValue ::= SEQUENCE {
58     infoType               OBJECT IDENTIFIER,
59     infoValue              ANY DEFINED BY infoType  OPTIONAL
60    }"""
61    componentType = namedtype.NamedTypes(
62        namedtype.NamedType('infoType', univ.ObjectIdentifier()),
63        namedtype.OptionalNamedType('infoValue', univ.Any())
64    )
65
66class GenRepContent(univ.SequenceOf):
67    componentType = InfoTypeAndValue()
68
69class GenMsgContent(univ.SequenceOf):
70    componentType = InfoTypeAndValue()
71
72class PKIConfirmContent(univ.Null): pass
73
74class CRLAnnContent(univ.SequenceOf):
75    componentType = rfc2459.CertificateList()
76
77class CAKeyUpdAnnContent(univ.Sequence):
78    """
79    CAKeyUpdAnnContent ::= SEQUENCE {
80         oldWithNew   CMPCertificate,
81         newWithOld   CMPCertificate,
82         newWithNew   CMPCertificate
83     }
84    """
85    componentType = namedtype.NamedTypes(
86        namedtype.NamedType('oldWithNew', CMPCertificate()),
87        namedtype.NamedType('newWithOld', CMPCertificate()),
88        namedtype.NamedType('newWithNew', CMPCertificate())
89    )
90
91class RevDetails(univ.Sequence):
92    """
93    RevDetails ::= SEQUENCE {
94         certDetails         CertTemplate,
95         crlEntryDetails     Extensions       OPTIONAL
96     }
97    """
98    componentType = namedtype.NamedTypes(
99        namedtype.NamedType('certDetails', rfc2511.CertTemplate()),
100        namedtype.OptionalNamedType('crlEntryDetails', rfc2459.Extensions())
101    )
102
103class RevReqContent(univ.SequenceOf):
104    componentType = RevDetails()
105
106class CertOrEncCert(univ.Choice):
107    """
108     CertOrEncCert ::= CHOICE {
109         certificate     [0] CMPCertificate,
110         encryptedCert   [1] EncryptedValue
111     }
112    """
113    componentType = namedtype.NamedTypes(
114        namedtype.NamedType('certificate', CMPCertificate().subtype(
115            explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0)
116            )
117        ),
118        namedtype.NamedType('encryptedCert', rfc2511.EncryptedValue().subtype(
119            explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)
120            )
121        )
122    )
123
124class CertifiedKeyPair(univ.Sequence):
125    """
126    CertifiedKeyPair ::= SEQUENCE {
127         certOrEncCert       CertOrEncCert,
128         privateKey      [0] EncryptedValue      OPTIONAL,
129         publicationInfo [1] PKIPublicationInfo  OPTIONAL
130     }
131    """
132    componentType = namedtype.NamedTypes(
133        namedtype.NamedType('certOrEncCert', CertOrEncCert()),
134        namedtype.OptionalNamedType('privateKey', rfc2511.EncryptedValue().subtype(
135                explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0)
136            )
137        ),
138        namedtype.OptionalNamedType('publicationInfo', rfc2511.PKIPublicationInfo().subtype(
139                explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)
140            )
141        )
142    )
143
144
145class POPODecKeyRespContent(univ.SequenceOf):
146    componentType = univ.Integer()
147
148class Challenge(univ.Sequence):
149    """
150    Challenge ::= SEQUENCE {
151         owf                 AlgorithmIdentifier  OPTIONAL,
152         witness             OCTET STRING,
153         challenge           OCTET STRING
154     }
155    """
156    componentType = namedtype.NamedTypes(
157        namedtype.OptionalNamedType('owf', rfc2459.AlgorithmIdentifier()),
158        namedtype.NamedType('witness', univ.OctetString()),
159        namedtype.NamedType('challenge', univ.OctetString())
160    )
161
162class PKIStatus(univ.Integer):
163    """
164    PKIStatus ::= INTEGER {
165         accepted                (0),
166         grantedWithMods        (1),
167         rejection              (2),
168         waiting                (3),
169         revocationWarning      (4),
170         revocationNotification (5),
171         keyUpdateWarning       (6)
172     }
173    """
174    namedValues = namedval.NamedValues(
175        ('accepted', 0),
176        ('grantedWithMods', 1),
177        ('rejection', 2),
178        ('waiting', 3),
179        ('revocationWarning', 4),
180        ('revocationNotification', 5),
181        ('keyUpdateWarning', 6)
182    )
183
184class PKIFailureInfo(univ.BitString):
185    """
186    PKIFailureInfo ::= BIT STRING {
187         badAlg              (0),
188         badMessageCheck     (1),
189         badRequest          (2),
190         badTime             (3),
191         badCertId           (4),
192         badDataFormat       (5),
193         wrongAuthority      (6),
194         incorrectData       (7),
195         missingTimeStamp    (8),
196         badPOP              (9),
197         certRevoked         (10),
198         certConfirmed       (11),
199         wrongIntegrity      (12),
200         badRecipientNonce   (13),
201         timeNotAvailable    (14),
202         unacceptedPolicy    (15),
203         unacceptedExtension (16),
204         addInfoNotAvailable (17),
205         badSenderNonce      (18),
206         badCertTemplate     (19),
207         signerNotTrusted    (20),
208         transactionIdInUse  (21),
209         unsupportedVersion  (22),
210         notAuthorized       (23),
211         systemUnavail       (24),
212         systemFailure       (25),
213         duplicateCertReq    (26)
214    """
215    namedValues = namedval.NamedValues(
216        ('badAlg', 0),
217        ('badMessageCheck', 1),
218        ('badRequest', 2),
219        ('badTime', 3),
220        ('badCertId', 4),
221        ('badDataFormat', 5),
222        ('wrongAuthority', 6),
223        ('incorrectData', 7),
224        ('missingTimeStamp', 8),
225        ('badPOP', 9),
226        ('certRevoked', 10),
227        ('certConfirmed', 11),
228        ('wrongIntegrity', 12),
229        ('badRecipientNonce', 13),
230        ('timeNotAvailable', 14),
231        ('unacceptedPolicy', 15),
232        ('unacceptedExtension', 16),
233        ('addInfoNotAvailable', 17),
234        ('badSenderNonce', 18),
235        ('badCertTemplate', 19),
236        ('signerNotTrusted', 20),
237        ('transactionIdInUse', 21),
238        ('unsupportedVersion', 22),
239        ('notAuthorized', 23),
240        ('systemUnavail', 24),
241        ('systemFailure', 25),
242        ('duplicateCertReq', 26)
243    )
244
245class PKIStatusInfo(univ.Sequence):
246    """
247    PKIStatusInfo ::= SEQUENCE {
248         status        PKIStatus,
249         statusString  PKIFreeText     OPTIONAL,
250         failInfo      PKIFailureInfo  OPTIONAL
251     }
252    """
253    componentType = namedtype.NamedTypes(
254        namedtype.NamedType('status', PKIStatus()),
255        namedtype.OptionalNamedType('statusString', PKIFreeText()),
256        namedtype.OptionalNamedType('failInfo', PKIFailureInfo())
257        )
258
259class ErrorMsgContent(univ.Sequence):
260    """
261    ErrorMsgContent ::= SEQUENCE {
262         pKIStatusInfo          PKIStatusInfo,
263         errorCode              INTEGER           OPTIONAL,
264         -- implementation-specific error codes
265         errorDetails           PKIFreeText       OPTIONAL
266         -- implementation-specific error details
267     }
268    """
269    componentType = namedtype.NamedTypes(
270        namedtype.NamedType('pKIStatusInfo', PKIStatusInfo()),
271        namedtype.OptionalNamedType('errorCode', univ.Integer()),
272        namedtype.OptionalNamedType('errorDetails', PKIFreeText())
273    )
274
275class CertStatus(univ.Sequence):
276    """
277    CertStatus ::= SEQUENCE {
278        certHash    OCTET STRING,
279        certReqId   INTEGER,
280        statusInfo  PKIStatusInfo OPTIONAL
281     }
282    """
283    componentType = namedtype.NamedTypes(
284        namedtype.NamedType('certHash', univ.OctetString()),
285        namedtype.NamedType('certReqId', univ.Integer()),
286        namedtype.OptionalNamedType('statusInfo', PKIStatusInfo())
287    )
288
289class CertConfirmContent(univ.SequenceOf):
290    componentType = CertStatus()
291
292class RevAnnContent(univ.Sequence):
293    """
294    RevAnnContent ::= SEQUENCE {
295         status              PKIStatus,
296         certId              CertId,
297         willBeRevokedAt     GeneralizedTime,
298         badSinceDate        GeneralizedTime,
299         crlDetails          Extensions  OPTIONAL
300     }
301    """
302    componentType = namedtype.NamedTypes(
303        namedtype.NamedType('status', PKIStatus()),
304        namedtype.NamedType('certId', rfc2511.CertId()),
305        namedtype.NamedType('willBeRevokedAt', useful.GeneralizedTime()),
306        namedtype.NamedType('badSinceDate', useful.GeneralizedTime()),
307        namedtype.OptionalNamedType('crlDetails', rfc2459.Extensions())
308    )
309
310class RevRepContent(univ.Sequence):
311    """
312    RevRepContent ::= SEQUENCE {
313         status       SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
314         revCerts [0] SEQUENCE SIZE (1..MAX) OF CertId
315                                             OPTIONAL,
316         crls     [1] SEQUENCE SIZE (1..MAX) OF CertificateList
317                                             OPTIONAL
318    """
319    componentType = namedtype.NamedTypes(
320        namedtype.NamedType('status', PKIStatusInfo()),
321        namedtype.OptionalNamedType('revCerts', univ.SequenceOf(
322                componentType=rfc2511.CertId()
323            ).subtype(
324                subtypeSpec=constraint.ValueSizeConstraint(1, MAX),
325                explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0)
326            )
327        ),
328        namedtype.OptionalNamedType('crls', univ.SequenceOf(
329                componentType=rfc2459.CertificateList()
330            ).subtype(
331                subtypeSpec=constraint.ValueSizeConstraint(1, MAX),
332                explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)
333            )
334        )
335    )
336
337class KeyRecRepContent(univ.Sequence):
338    """
339    KeyRecRepContent ::= SEQUENCE {
340         status                  PKIStatusInfo,
341         newSigCert          [0] CMPCertificate OPTIONAL,
342         caCerts             [1] SEQUENCE SIZE (1..MAX) OF
343                                             CMPCertificate OPTIONAL,
344         keyPairHist         [2] SEQUENCE SIZE (1..MAX) OF
345                                             CertifiedKeyPair OPTIONAL
346     }
347    """
348    componentType = namedtype.NamedTypes(
349        namedtype.NamedType('status', PKIStatusInfo()),
350        namedtype.OptionalNamedType('newSigCert', CMPCertificate().subtype(
351            explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0)
352            )
353        ),
354        namedtype.OptionalNamedType('caCerts', univ.SequenceOf(
355                componentType=CMPCertificate()
356            ).subtype(
357                explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1),
358                subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
359            )
360        ),
361        namedtype.OptionalNamedType('keyPairHist', univ.SequenceOf(
362                componentType=CertifiedKeyPair()
363            ).subtype(
364                explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2),
365                subtypeSpec=constraint.ValueSizeConstraint(1, MAX)
366            )
367        )
368    )
369
370class CertResponse(univ.Sequence):
371    """
372    CertResponse ::= SEQUENCE {
373         certReqId           INTEGER,
374         status              PKIStatusInfo,
375         certifiedKeyPair    CertifiedKeyPair    OPTIONAL,
376         rspInfo             OCTET STRING        OPTIONAL
377     }
378    """
379    componentType = namedtype.NamedTypes(
380        namedtype.NamedType('certReqId', univ.Integer()),
381        namedtype.NamedType('status', PKIStatusInfo()),
382        namedtype.OptionalNamedType('certifiedKeyPair', CertifiedKeyPair()),
383        namedtype.OptionalNamedType('rspInfo', univ.OctetString())
384    )
385
386class CertRepMessage(univ.Sequence):
387    """
388    CertRepMessage ::= SEQUENCE {
389         caPubs       [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
390                          OPTIONAL,
391         response         SEQUENCE OF CertResponse
392     }
393    """
394    componentType = namedtype.NamedTypes(
395        namedtype.OptionalNamedType('caPubs', univ.SequenceOf(
396                componentType=CMPCertificate()
397            ).subtype(
398                subtypeSpec=constraint.ValueSizeConstraint(1, MAX),
399                explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,1)
400            )
401        ),
402        namedtype.NamedType('response', univ.SequenceOf(
403                componentType=CertResponse())
404            )
405    )
406
407class POPODecKeyChallContent(univ.SequenceOf):
408    componentType = Challenge()
409
410class OOBCertHash(univ.Sequence):
411    """
412    OOBCertHash ::= SEQUENCE {
413         hashAlg     [0] AlgorithmIdentifier     OPTIONAL,
414         certId      [1] CertId                  OPTIONAL,
415         hashVal         BIT STRING
416     }
417    """
418    componentType = namedtype.NamedTypes(
419        namedtype.OptionalNamedType('hashAlg',
420                                    rfc2459.AlgorithmIdentifier().subtype(
421            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,0)
422            )
423        ),
424        namedtype.OptionalNamedType('certId', rfc2511.CertId().subtype(
425            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,1)
426            )
427        ),
428        namedtype.NamedType('hashVal', univ.BitString())
429    )
430
431# pyasn1 does not naturally handle recursive definitions, thus this hack:
432# NestedMessageContent ::= PKIMessages
433class NestedMessageContent(univ.SequenceOf):
434    """
435    NestedMessageContent ::= PKIMessages
436    """
437    componentType = univ.Any()
438
439class DHBMParameter(univ.Sequence):
440    """
441    DHBMParameter ::= SEQUENCE {
442         owf                 AlgorithmIdentifier,
443         -- AlgId for a One-Way Function (SHA-1 recommended)
444         mac                 AlgorithmIdentifier
445         -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11],
446     }   -- or HMAC [RFC2104, RFC2202])
447    """
448    componentType = namedtype.NamedTypes(
449        namedtype.NamedType('owf', rfc2459.AlgorithmIdentifier()),
450        namedtype.NamedType('mac', rfc2459.AlgorithmIdentifier())
451    )
452
453id_DHBasedMac = univ.ObjectIdentifier('1.2.840.113533.7.66.30')
454
455class PBMParameter(univ.Sequence):
456    """
457    PBMParameter ::= SEQUENCE {
458         salt                OCTET STRING,
459         owf                 AlgorithmIdentifier,
460         iterationCount      INTEGER,
461         mac                 AlgorithmIdentifier
462     }
463    """
464    componentType = namedtype.NamedTypes(
465        namedtype.NamedType('salt', univ.OctetString().subtype(
466                subtypeSpec=constraint.ValueSizeConstraint(0, 128)
467            )
468        ),
469        namedtype.NamedType('owf', rfc2459.AlgorithmIdentifier()),
470        namedtype.NamedType('iterationCount', univ.Integer()),
471        namedtype.NamedType('mac', rfc2459.AlgorithmIdentifier())
472    )
473
474id_PasswordBasedMac = univ.ObjectIdentifier('1.2.840.113533.7.66.13')
475
476class PKIProtection(univ.BitString): pass
477
478# pyasn1 does not naturally handle recursive definitions, thus this hack:
479# NestedMessageContent ::= PKIMessages
480nestedMessageContent = NestedMessageContent().subtype(explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,20))
481
482class PKIBody(univ.Choice):
483    """
484    PKIBody ::= CHOICE {       -- message-specific body elements
485         ir       [0]  CertReqMessages,        --Initialization Request
486         ip       [1]  CertRepMessage,         --Initialization Response
487         cr       [2]  CertReqMessages,        --Certification Request
488         cp       [3]  CertRepMessage,         --Certification Response
489         p10cr    [4]  CertificationRequest,   --imported from [PKCS10]
490         popdecc  [5]  POPODecKeyChallContent, --pop Challenge
491         popdecr  [6]  POPODecKeyRespContent,  --pop Response
492         kur      [7]  CertReqMessages,        --Key Update Request
493         kup      [8]  CertRepMessage,         --Key Update Response
494         krr      [9]  CertReqMessages,        --Key Recovery Request
495         krp      [10] KeyRecRepContent,       --Key Recovery Response
496         rr       [11] RevReqContent,          --Revocation Request
497         rp       [12] RevRepContent,          --Revocation Response
498         ccr      [13] CertReqMessages,        --Cross-Cert. Request
499         ccp      [14] CertRepMessage,         --Cross-Cert. Response
500         ckuann   [15] CAKeyUpdAnnContent,     --CA Key Update Ann.
501         cann     [16] CertAnnContent,         --Certificate Ann.
502         rann     [17] RevAnnContent,          --Revocation Ann.
503         crlann   [18] CRLAnnContent,          --CRL Announcement
504         pkiconf  [19] PKIConfirmContent,      --Confirmation
505         nested   [20] NestedMessageContent,   --Nested Message
506         genm     [21] GenMsgContent,          --General Message
507         genp     [22] GenRepContent,          --General Response
508         error    [23] ErrorMsgContent,        --Error Message
509         certConf [24] CertConfirmContent,     --Certificate confirm
510         pollReq  [25] PollReqContent,         --Polling request
511         pollRep  [26] PollRepContent          --Polling response
512
513    """
514    componentType = namedtype.NamedTypes(
515        namedtype.NamedType('ir', rfc2511.CertReqMessages().subtype(
516            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,0)
517            )
518        ),
519        namedtype.NamedType('ip', CertRepMessage().subtype(
520            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,1)
521            )
522        ),
523        namedtype.NamedType('cr', rfc2511.CertReqMessages().subtype(
524            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,2)
525            )
526        ),
527        namedtype.NamedType('cp', CertRepMessage().subtype(
528            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,3)
529            )
530        ),
531        namedtype.NamedType('p10cr', rfc2314.CertificationRequest().subtype(
532            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,4)
533            )
534        ),
535        namedtype.NamedType('popdecc', POPODecKeyChallContent().subtype(
536            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,5)
537            )
538        ),
539        namedtype.NamedType('popdecr', POPODecKeyRespContent().subtype(
540            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,6)
541            )
542        ),
543        namedtype.NamedType('kur', rfc2511.CertReqMessages().subtype(
544            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,7)
545            )
546        ),
547        namedtype.NamedType('kup', CertRepMessage().subtype(
548            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,8)
549            )
550        ),
551        namedtype.NamedType('krr', rfc2511.CertReqMessages().subtype(
552            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,9)
553            )
554        ),
555        namedtype.NamedType('krp', KeyRecRepContent().subtype(
556            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,10)
557            )
558        ),
559        namedtype.NamedType('rr', RevReqContent().subtype(
560            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,11)
561            )
562        ),
563        namedtype.NamedType('rp', RevRepContent().subtype(
564            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,12)
565            )
566        ),
567        namedtype.NamedType('ccr', rfc2511.CertReqMessages().subtype(
568            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,13)
569            )
570        ),
571        namedtype.NamedType('ccp', CertRepMessage().subtype(
572            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,14)
573            )
574        ),
575        namedtype.NamedType('ckuann', CAKeyUpdAnnContent().subtype(
576            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,15)
577            )
578        ),
579        namedtype.NamedType('cann', CertAnnContent().subtype(
580            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,16)
581            )
582        ),
583        namedtype.NamedType('rann', RevAnnContent().subtype(
584            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,17)
585            )
586        ),
587        namedtype.NamedType('crlann', CRLAnnContent().subtype(
588            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,18)
589            )
590        ),
591        namedtype.NamedType('pkiconf', PKIConfirmContent().subtype(
592            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,19)
593            )
594        ),
595        namedtype.NamedType('nested', nestedMessageContent),
596#        namedtype.NamedType('nested', NestedMessageContent().subtype(
597#            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,20)
598#            )
599#        ),
600        namedtype.NamedType('genm', GenMsgContent().subtype(
601            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,21)
602            )
603        ),
604        namedtype.NamedType('gen', GenRepContent().subtype(
605            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,22)
606            )
607        ),
608        namedtype.NamedType('error', ErrorMsgContent().subtype(
609            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,23)
610            )
611        ),
612        namedtype.NamedType('certConf', CertConfirmContent().subtype(
613            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,24)
614            )
615        ),
616        namedtype.NamedType('pollReq', PollReqContent().subtype(
617            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,25)
618            )
619        ),
620        namedtype.NamedType('pollRep', PollRepContent().subtype(
621            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,26)
622            )
623        )
624    )
625
626
627class PKIHeader(univ.Sequence):
628    """
629    PKIHeader ::= SEQUENCE {
630    pvno                INTEGER     { cmp1999(1), cmp2000(2) },
631    sender              GeneralName,
632    recipient           GeneralName,
633    messageTime     [0] GeneralizedTime         OPTIONAL,
634    protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
635    senderKID       [2] KeyIdentifier           OPTIONAL,
636    recipKID        [3] KeyIdentifier           OPTIONAL,
637    transactionID   [4] OCTET STRING            OPTIONAL,
638    senderNonce     [5] OCTET STRING            OPTIONAL,
639    recipNonce      [6] OCTET STRING            OPTIONAL,
640    freeText        [7] PKIFreeText             OPTIONAL,
641    generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
642                     InfoTypeAndValue     OPTIONAL
643    }
644
645    """
646    componentType = namedtype.NamedTypes(
647        namedtype.NamedType('pvno', univ.Integer(
648                namedValues=namedval.NamedValues(
649                    ('cmp1999', 1),
650                    ('cmp2000', 2)
651                )
652            )
653        ),
654        namedtype.NamedType('sender', rfc2459.GeneralName()),
655        namedtype.NamedType('recipient', rfc2459.GeneralName()),
656        namedtype.OptionalNamedType('messageTime', useful.GeneralizedTime().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
657        namedtype.OptionalNamedType('protectionAlg', rfc2459.AlgorithmIdentifier().subtype(
658            explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))),
659        namedtype.OptionalNamedType('senderKID', rfc2459.KeyIdentifier().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))),
660        namedtype.OptionalNamedType('recipKID', rfc2459.KeyIdentifier().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))),
661        namedtype.OptionalNamedType('transactionID', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))),
662        namedtype.OptionalNamedType('senderNonce', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))),
663        namedtype.OptionalNamedType('recipNonce', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))),
664        namedtype.OptionalNamedType('freeText', PKIFreeText().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 7))),
665        namedtype.OptionalNamedType('generalInfo',
666            univ.SequenceOf(
667                componentType=InfoTypeAndValue().subtype(
668                    subtypeSpec=constraint.ValueSizeConstraint(1, MAX),
669                    explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8)
670                    )
671                )
672            )
673        )
674
675class ProtectedPart(univ.Sequence):
676    """
677     ProtectedPart ::= SEQUENCE {
678         header    PKIHeader,
679         body      PKIBody
680     }
681    """
682    componentType = namedtype.NamedTypes(
683        namedtype.NamedType('header', PKIHeader()),
684        namedtype.NamedType('infoValue', PKIBody())
685        )
686
687class PKIMessage(univ.Sequence):
688    """
689    PKIMessage ::= SEQUENCE {
690    header           PKIHeader,
691    body             PKIBody,
692    protection   [0] PKIProtection OPTIONAL,
693    extraCerts   [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
694                  OPTIONAL
695     }"""
696    componentType = namedtype.NamedTypes(
697        namedtype.NamedType('header', PKIHeader()),
698        namedtype.NamedType('body', PKIBody()),
699        namedtype.OptionalNamedType('protection', PKIProtection().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
700        namedtype.OptionalNamedType( 'extraCerts',
701            univ.SequenceOf(
702                componentType=CMPCertificate()
703            ).subtype(
704                subtypeSpec=constraint.ValueSizeConstraint(1, MAX),
705                explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1)
706            )
707        )
708    )
709
710class PKIMessages(univ.SequenceOf):
711    """
712    PKIMessages ::= SEQUENCE SIZE (1..MAX) OF PKIMessage
713    """
714    componentType = PKIMessage()
715    subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX)
716
717# pyasn1 does not naturally handle recursive definitions, thus this hack:
718# NestedMessageContent ::= PKIMessages
719NestedMessageContent.componentType = PKIMessages()
720nestedMessageContent.componentType = PKIMessages()
721