Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | /* |
michael@0 | 5 | * certt.h - public data structures for the certificate library |
michael@0 | 6 | */ |
michael@0 | 7 | #ifndef _PCERTT_H_ |
michael@0 | 8 | #define _PCERTT_H_ |
michael@0 | 9 | |
michael@0 | 10 | #include "prclist.h" |
michael@0 | 11 | #include "pkcs11t.h" |
michael@0 | 12 | #include "seccomon.h" |
michael@0 | 13 | #include "secoidt.h" |
michael@0 | 14 | #include "plarena.h" |
michael@0 | 15 | #include "prcvar.h" |
michael@0 | 16 | #include "nssilock.h" |
michael@0 | 17 | #include "prio.h" |
michael@0 | 18 | #include "prmon.h" |
michael@0 | 19 | |
michael@0 | 20 | /* Non-opaque objects */ |
michael@0 | 21 | typedef struct NSSLOWCERTCertDBHandleStr NSSLOWCERTCertDBHandle; |
michael@0 | 22 | typedef struct NSSLOWCERTCertKeyStr NSSLOWCERTCertKey; |
michael@0 | 23 | |
michael@0 | 24 | typedef struct NSSLOWCERTTrustStr NSSLOWCERTTrust; |
michael@0 | 25 | typedef struct NSSLOWCERTCertTrustStr NSSLOWCERTCertTrust; |
michael@0 | 26 | typedef struct NSSLOWCERTCertificateStr NSSLOWCERTCertificate; |
michael@0 | 27 | typedef struct NSSLOWCERTCertificateListStr NSSLOWCERTCertificateList; |
michael@0 | 28 | typedef struct NSSLOWCERTIssuerAndSNStr NSSLOWCERTIssuerAndSN; |
michael@0 | 29 | typedef struct NSSLOWCERTSignedDataStr NSSLOWCERTSignedData; |
michael@0 | 30 | typedef struct NSSLOWCERTSubjectPublicKeyInfoStr NSSLOWCERTSubjectPublicKeyInfo; |
michael@0 | 31 | typedef struct NSSLOWCERTValidityStr NSSLOWCERTValidity; |
michael@0 | 32 | |
michael@0 | 33 | /* |
michael@0 | 34 | ** An X.509 validity object |
michael@0 | 35 | */ |
michael@0 | 36 | struct NSSLOWCERTValidityStr { |
michael@0 | 37 | PLArenaPool *arena; |
michael@0 | 38 | SECItem notBefore; |
michael@0 | 39 | SECItem notAfter; |
michael@0 | 40 | }; |
michael@0 | 41 | |
michael@0 | 42 | /* |
michael@0 | 43 | * A serial number and issuer name, which is used as a database key |
michael@0 | 44 | */ |
michael@0 | 45 | struct NSSLOWCERTCertKeyStr { |
michael@0 | 46 | SECItem serialNumber; |
michael@0 | 47 | SECItem derIssuer; |
michael@0 | 48 | }; |
michael@0 | 49 | |
michael@0 | 50 | /* |
michael@0 | 51 | ** A signed data object. Used to implement the "signed" macro used |
michael@0 | 52 | ** in the X.500 specs. |
michael@0 | 53 | */ |
michael@0 | 54 | struct NSSLOWCERTSignedDataStr { |
michael@0 | 55 | SECItem data; |
michael@0 | 56 | SECAlgorithmID signatureAlgorithm; |
michael@0 | 57 | SECItem signature; |
michael@0 | 58 | }; |
michael@0 | 59 | |
michael@0 | 60 | /* |
michael@0 | 61 | ** An X.509 subject-public-key-info object |
michael@0 | 62 | */ |
michael@0 | 63 | struct NSSLOWCERTSubjectPublicKeyInfoStr { |
michael@0 | 64 | PLArenaPool *arena; |
michael@0 | 65 | SECAlgorithmID algorithm; |
michael@0 | 66 | SECItem subjectPublicKey; |
michael@0 | 67 | }; |
michael@0 | 68 | |
michael@0 | 69 | typedef struct _certDBEntryCert certDBEntryCert; |
michael@0 | 70 | typedef struct _certDBEntryRevocation certDBEntryRevocation; |
michael@0 | 71 | |
michael@0 | 72 | struct NSSLOWCERTCertTrustStr { |
michael@0 | 73 | unsigned int sslFlags; |
michael@0 | 74 | unsigned int emailFlags; |
michael@0 | 75 | unsigned int objectSigningFlags; |
michael@0 | 76 | }; |
michael@0 | 77 | |
michael@0 | 78 | /* |
michael@0 | 79 | ** PKCS11 Trust representation |
michael@0 | 80 | */ |
michael@0 | 81 | struct NSSLOWCERTTrustStr { |
michael@0 | 82 | NSSLOWCERTTrust *next; |
michael@0 | 83 | NSSLOWCERTCertDBHandle *dbhandle; |
michael@0 | 84 | SECItem dbKey; /* database key for this cert */ |
michael@0 | 85 | certDBEntryCert *dbEntry; /* database entry struct */ |
michael@0 | 86 | NSSLOWCERTCertTrust *trust; |
michael@0 | 87 | SECItem *derCert; /* original DER for the cert */ |
michael@0 | 88 | unsigned char dbKeySpace[512]; |
michael@0 | 89 | }; |
michael@0 | 90 | |
michael@0 | 91 | /* |
michael@0 | 92 | ** An X.509 certificate object (the unsigned form) |
michael@0 | 93 | */ |
michael@0 | 94 | struct NSSLOWCERTCertificateStr { |
michael@0 | 95 | /* the arena is used to allocate any data structures that have the same |
michael@0 | 96 | * lifetime as the cert. This is all stuff that hangs off of the cert |
michael@0 | 97 | * structure, and is all freed at the same time. I is used when the |
michael@0 | 98 | * cert is decoded, destroyed, and at some times when it changes |
michael@0 | 99 | * state |
michael@0 | 100 | */ |
michael@0 | 101 | NSSLOWCERTCertificate *next; |
michael@0 | 102 | NSSLOWCERTCertDBHandle *dbhandle; |
michael@0 | 103 | |
michael@0 | 104 | SECItem derCert; /* original DER for the cert */ |
michael@0 | 105 | SECItem derIssuer; /* DER for issuer name */ |
michael@0 | 106 | SECItem derSN; |
michael@0 | 107 | SECItem serialNumber; |
michael@0 | 108 | SECItem derSubject; /* DER for subject name */ |
michael@0 | 109 | SECItem derSubjKeyInfo; |
michael@0 | 110 | NSSLOWCERTSubjectPublicKeyInfo *subjectPublicKeyInfo; |
michael@0 | 111 | SECItem certKey; /* database key for this cert */ |
michael@0 | 112 | SECItem validity; |
michael@0 | 113 | certDBEntryCert *dbEntry; /* database entry struct */ |
michael@0 | 114 | SECItem subjectKeyID; /* x509v3 subject key identifier */ |
michael@0 | 115 | SECItem extensions; |
michael@0 | 116 | char *nickname; |
michael@0 | 117 | char *emailAddr; |
michael@0 | 118 | NSSLOWCERTCertTrust *trust; |
michael@0 | 119 | |
michael@0 | 120 | /* the reference count is modified whenever someone looks up, dups |
michael@0 | 121 | * or destroys a certificate |
michael@0 | 122 | */ |
michael@0 | 123 | int referenceCount; |
michael@0 | 124 | |
michael@0 | 125 | char nicknameSpace[200]; |
michael@0 | 126 | char emailAddrSpace[200]; |
michael@0 | 127 | unsigned char certKeySpace[512]; |
michael@0 | 128 | }; |
michael@0 | 129 | |
michael@0 | 130 | #define SEC_CERTIFICATE_VERSION_1 0 /* default created */ |
michael@0 | 131 | #define SEC_CERTIFICATE_VERSION_2 1 /* v2 */ |
michael@0 | 132 | #define SEC_CERTIFICATE_VERSION_3 2 /* v3 extensions */ |
michael@0 | 133 | |
michael@0 | 134 | #define SEC_CRL_VERSION_1 0 /* default */ |
michael@0 | 135 | #define SEC_CRL_VERSION_2 1 /* v2 extensions */ |
michael@0 | 136 | |
michael@0 | 137 | #define NSS_MAX_LEGACY_DB_KEY_SIZE (60 * 1024) |
michael@0 | 138 | |
michael@0 | 139 | struct NSSLOWCERTIssuerAndSNStr { |
michael@0 | 140 | SECItem derIssuer; |
michael@0 | 141 | SECItem serialNumber; |
michael@0 | 142 | }; |
michael@0 | 143 | |
michael@0 | 144 | typedef SECStatus (* NSSLOWCERTCertCallback)(NSSLOWCERTCertificate *cert, void *arg); |
michael@0 | 145 | |
michael@0 | 146 | /* This is the typedef for the callback passed to nsslowcert_OpenCertDB() */ |
michael@0 | 147 | /* callback to return database name based on version number */ |
michael@0 | 148 | typedef char * (*NSSLOWCERTDBNameFunc)(void *arg, int dbVersion); |
michael@0 | 149 | |
michael@0 | 150 | /* XXX Lisa thinks the template declarations belong in cert.h, not here? */ |
michael@0 | 151 | |
michael@0 | 152 | #include "secasn1t.h" /* way down here because I expect template stuff to |
michael@0 | 153 | * move out of here anyway */ |
michael@0 | 154 | |
michael@0 | 155 | /* |
michael@0 | 156 | * Certificate Database related definitions and data structures |
michael@0 | 157 | */ |
michael@0 | 158 | |
michael@0 | 159 | /* version number of certificate database */ |
michael@0 | 160 | #define CERT_DB_FILE_VERSION 8 |
michael@0 | 161 | #define CERT_DB_V7_FILE_VERSION 7 |
michael@0 | 162 | #define CERT_DB_CONTENT_VERSION 2 |
michael@0 | 163 | |
michael@0 | 164 | #define SEC_DB_ENTRY_HEADER_LEN 3 |
michael@0 | 165 | #define SEC_DB_KEY_HEADER_LEN 1 |
michael@0 | 166 | |
michael@0 | 167 | /* All database entries have this form: |
michael@0 | 168 | * |
michael@0 | 169 | * byte offset field |
michael@0 | 170 | * ----------- ----- |
michael@0 | 171 | * 0 version |
michael@0 | 172 | * 1 type |
michael@0 | 173 | * 2 flags |
michael@0 | 174 | */ |
michael@0 | 175 | |
michael@0 | 176 | /* database entry types */ |
michael@0 | 177 | typedef enum { |
michael@0 | 178 | certDBEntryTypeVersion = 0, |
michael@0 | 179 | certDBEntryTypeCert = 1, |
michael@0 | 180 | certDBEntryTypeNickname = 2, |
michael@0 | 181 | certDBEntryTypeSubject = 3, |
michael@0 | 182 | certDBEntryTypeRevocation = 4, |
michael@0 | 183 | certDBEntryTypeKeyRevocation = 5, |
michael@0 | 184 | certDBEntryTypeSMimeProfile = 6, |
michael@0 | 185 | certDBEntryTypeContentVersion = 7, |
michael@0 | 186 | certDBEntryTypeBlob = 8 |
michael@0 | 187 | } certDBEntryType; |
michael@0 | 188 | |
michael@0 | 189 | typedef struct { |
michael@0 | 190 | certDBEntryType type; |
michael@0 | 191 | unsigned int version; |
michael@0 | 192 | unsigned int flags; |
michael@0 | 193 | PLArenaPool *arena; |
michael@0 | 194 | } certDBEntryCommon; |
michael@0 | 195 | |
michael@0 | 196 | /* |
michael@0 | 197 | * Certificate entry: |
michael@0 | 198 | * |
michael@0 | 199 | * byte offset field |
michael@0 | 200 | * ----------- ----- |
michael@0 | 201 | * 0 sslFlags-msb |
michael@0 | 202 | * 1 sslFlags-lsb |
michael@0 | 203 | * 2 emailFlags-msb |
michael@0 | 204 | * 3 emailFlags-lsb |
michael@0 | 205 | * 4 objectSigningFlags-msb |
michael@0 | 206 | * 5 objectSigningFlags-lsb |
michael@0 | 207 | * 6 derCert-len-msb |
michael@0 | 208 | * 7 derCert-len-lsb |
michael@0 | 209 | * 8 nickname-len-msb |
michael@0 | 210 | * 9 nickname-len-lsb |
michael@0 | 211 | * ... derCert |
michael@0 | 212 | * ... nickname |
michael@0 | 213 | * |
michael@0 | 214 | * NOTE: the nickname string as stored in the database is null terminated, |
michael@0 | 215 | * in other words, the last byte of the db entry is always 0 |
michael@0 | 216 | * if a nickname is present. |
michael@0 | 217 | * NOTE: if nickname is not present, then nickname-len-msb and |
michael@0 | 218 | * nickname-len-lsb will both be zero. |
michael@0 | 219 | */ |
michael@0 | 220 | struct _certDBEntryCert { |
michael@0 | 221 | certDBEntryCommon common; |
michael@0 | 222 | certDBEntryCert *next; |
michael@0 | 223 | NSSLOWCERTCertTrust trust; |
michael@0 | 224 | SECItem derCert; |
michael@0 | 225 | char *nickname; |
michael@0 | 226 | char nicknameSpace[200]; |
michael@0 | 227 | unsigned char derCertSpace[2048]; |
michael@0 | 228 | }; |
michael@0 | 229 | |
michael@0 | 230 | /* |
michael@0 | 231 | * Certificate Nickname entry: |
michael@0 | 232 | * |
michael@0 | 233 | * byte offset field |
michael@0 | 234 | * ----------- ----- |
michael@0 | 235 | * 0 subjectname-len-msb |
michael@0 | 236 | * 1 subjectname-len-lsb |
michael@0 | 237 | * 2... subjectname |
michael@0 | 238 | * |
michael@0 | 239 | * The database key for this type of entry is a nickname string |
michael@0 | 240 | * The "subjectname" value is the DER encoded DN of the identity |
michael@0 | 241 | * that matches this nickname. |
michael@0 | 242 | */ |
michael@0 | 243 | typedef struct { |
michael@0 | 244 | certDBEntryCommon common; |
michael@0 | 245 | char *nickname; |
michael@0 | 246 | SECItem subjectName; |
michael@0 | 247 | } certDBEntryNickname; |
michael@0 | 248 | |
michael@0 | 249 | #define DB_NICKNAME_ENTRY_HEADER_LEN 2 |
michael@0 | 250 | |
michael@0 | 251 | /* |
michael@0 | 252 | * Certificate Subject entry: |
michael@0 | 253 | * |
michael@0 | 254 | * byte offset field |
michael@0 | 255 | * ----------- ----- |
michael@0 | 256 | * 0 ncerts-msb |
michael@0 | 257 | * 1 ncerts-lsb |
michael@0 | 258 | * 2 nickname-msb |
michael@0 | 259 | * 3 nickname-lsb |
michael@0 | 260 | * 4 emailAddr-msb |
michael@0 | 261 | * 5 emailAddr-lsb |
michael@0 | 262 | * ... nickname |
michael@0 | 263 | * ... emailAddr |
michael@0 | 264 | * ...+2*i certkey-len-msb |
michael@0 | 265 | * ...+1+2*i certkey-len-lsb |
michael@0 | 266 | * ...+2*ncerts+2*i keyid-len-msb |
michael@0 | 267 | * ...+1+2*ncerts+2*i keyid-len-lsb |
michael@0 | 268 | * ... certkeys |
michael@0 | 269 | * ... keyids |
michael@0 | 270 | * |
michael@0 | 271 | * The database key for this type of entry is the DER encoded subject name |
michael@0 | 272 | * The "certkey" value is an array of certificate database lookup keys that |
michael@0 | 273 | * points to the database entries for the certificates that matche |
michael@0 | 274 | * this subject. |
michael@0 | 275 | * |
michael@0 | 276 | */ |
michael@0 | 277 | typedef struct _certDBEntrySubject { |
michael@0 | 278 | certDBEntryCommon common; |
michael@0 | 279 | SECItem derSubject; |
michael@0 | 280 | unsigned int ncerts; |
michael@0 | 281 | char *nickname; |
michael@0 | 282 | SECItem *certKeys; |
michael@0 | 283 | SECItem *keyIDs; |
michael@0 | 284 | char **emailAddrs; |
michael@0 | 285 | unsigned int nemailAddrs; |
michael@0 | 286 | } certDBEntrySubject; |
michael@0 | 287 | |
michael@0 | 288 | #define DB_SUBJECT_ENTRY_HEADER_LEN 6 |
michael@0 | 289 | |
michael@0 | 290 | /* |
michael@0 | 291 | * Certificate SMIME profile entry: |
michael@0 | 292 | * |
michael@0 | 293 | * byte offset field |
michael@0 | 294 | * ----------- ----- |
michael@0 | 295 | * 0 subjectname-len-msb |
michael@0 | 296 | * 1 subjectname-len-lsb |
michael@0 | 297 | * 2 smimeoptions-len-msb |
michael@0 | 298 | * 3 smimeoptions-len-lsb |
michael@0 | 299 | * 4 options-date-len-msb |
michael@0 | 300 | * 5 options-date-len-lsb |
michael@0 | 301 | * 6... subjectname |
michael@0 | 302 | * ... smimeoptions |
michael@0 | 303 | * ... options-date |
michael@0 | 304 | * |
michael@0 | 305 | * The database key for this type of entry is the email address string |
michael@0 | 306 | * The "subjectname" value is the DER encoded DN of the identity |
michael@0 | 307 | * that matches this nickname. |
michael@0 | 308 | * The "smimeoptions" value is a string that represents the algorithm |
michael@0 | 309 | * capabilities on the remote user. |
michael@0 | 310 | * The "options-date" is the date that the smime options value was created. |
michael@0 | 311 | * This is generally the signing time of the signed message that contained |
michael@0 | 312 | * the options. It is a UTCTime value. |
michael@0 | 313 | */ |
michael@0 | 314 | typedef struct { |
michael@0 | 315 | certDBEntryCommon common; |
michael@0 | 316 | char *emailAddr; |
michael@0 | 317 | SECItem subjectName; |
michael@0 | 318 | SECItem smimeOptions; |
michael@0 | 319 | SECItem optionsDate; |
michael@0 | 320 | } certDBEntrySMime; |
michael@0 | 321 | |
michael@0 | 322 | #define DB_SMIME_ENTRY_HEADER_LEN 6 |
michael@0 | 323 | |
michael@0 | 324 | /* |
michael@0 | 325 | * Crl/krl entry: |
michael@0 | 326 | * |
michael@0 | 327 | * byte offset field |
michael@0 | 328 | * ----------- ----- |
michael@0 | 329 | * 0 derCert-len-msb |
michael@0 | 330 | * 1 derCert-len-lsb |
michael@0 | 331 | * 2 url-len-msb |
michael@0 | 332 | * 3 url-len-lsb |
michael@0 | 333 | * ... derCert |
michael@0 | 334 | * ... url |
michael@0 | 335 | * |
michael@0 | 336 | * NOTE: the url string as stored in the database is null terminated, |
michael@0 | 337 | * in other words, the last byte of the db entry is always 0 |
michael@0 | 338 | * if a nickname is present. |
michael@0 | 339 | * NOTE: if url is not present, then url-len-msb and |
michael@0 | 340 | * url-len-lsb will both be zero. |
michael@0 | 341 | */ |
michael@0 | 342 | #define DB_CRL_ENTRY_HEADER_LEN 4 |
michael@0 | 343 | struct _certDBEntryRevocation { |
michael@0 | 344 | certDBEntryCommon common; |
michael@0 | 345 | SECItem derCrl; |
michael@0 | 346 | char *url; /* where to load the crl from */ |
michael@0 | 347 | }; |
michael@0 | 348 | |
michael@0 | 349 | /* |
michael@0 | 350 | * Database Version Entry: |
michael@0 | 351 | * |
michael@0 | 352 | * byte offset field |
michael@0 | 353 | * ----------- ----- |
michael@0 | 354 | * only the low level header... |
michael@0 | 355 | * |
michael@0 | 356 | * The database key for this type of entry is the string "Version" |
michael@0 | 357 | */ |
michael@0 | 358 | typedef struct { |
michael@0 | 359 | certDBEntryCommon common; |
michael@0 | 360 | } certDBEntryVersion; |
michael@0 | 361 | |
michael@0 | 362 | #define SEC_DB_VERSION_KEY "Version" |
michael@0 | 363 | #define SEC_DB_VERSION_KEY_LEN sizeof(SEC_DB_VERSION_KEY) |
michael@0 | 364 | |
michael@0 | 365 | /* |
michael@0 | 366 | * Database Content Version Entry: |
michael@0 | 367 | * |
michael@0 | 368 | * byte offset field |
michael@0 | 369 | * ----------- ----- |
michael@0 | 370 | * 0 contentVersion |
michael@0 | 371 | * |
michael@0 | 372 | * The database key for this type of entry is the string "ContentVersion" |
michael@0 | 373 | */ |
michael@0 | 374 | typedef struct { |
michael@0 | 375 | certDBEntryCommon common; |
michael@0 | 376 | char contentVersion; |
michael@0 | 377 | } certDBEntryContentVersion; |
michael@0 | 378 | |
michael@0 | 379 | #define SEC_DB_CONTENT_VERSION_KEY "ContentVersion" |
michael@0 | 380 | #define SEC_DB_CONTENT_VERSION_KEY_LEN sizeof(SEC_DB_CONTENT_VERSION_KEY) |
michael@0 | 381 | |
michael@0 | 382 | typedef union { |
michael@0 | 383 | certDBEntryCommon common; |
michael@0 | 384 | certDBEntryCert cert; |
michael@0 | 385 | certDBEntryContentVersion content; |
michael@0 | 386 | certDBEntryNickname nickname; |
michael@0 | 387 | certDBEntryRevocation revocation; |
michael@0 | 388 | certDBEntrySMime smime; |
michael@0 | 389 | certDBEntrySubject subject; |
michael@0 | 390 | certDBEntryVersion version; |
michael@0 | 391 | } certDBEntry; |
michael@0 | 392 | |
michael@0 | 393 | /* length of the fixed part of a database entry */ |
michael@0 | 394 | #define DBCERT_V4_HEADER_LEN 7 |
michael@0 | 395 | #define DB_CERT_V5_ENTRY_HEADER_LEN 7 |
michael@0 | 396 | #define DB_CERT_V6_ENTRY_HEADER_LEN 7 |
michael@0 | 397 | #define DB_CERT_ENTRY_HEADER_LEN 10 |
michael@0 | 398 | |
michael@0 | 399 | /* common flags for all types of certificates */ |
michael@0 | 400 | #define CERTDB_TERMINAL_RECORD (1u<<0) |
michael@0 | 401 | #define CERTDB_TRUSTED (1u<<1) |
michael@0 | 402 | #define CERTDB_SEND_WARN (1u<<2) |
michael@0 | 403 | #define CERTDB_VALID_CA (1u<<3) |
michael@0 | 404 | #define CERTDB_TRUSTED_CA (1u<<4) /* trusted for issuing server certs */ |
michael@0 | 405 | #define CERTDB_NS_TRUSTED_CA (1u<<5) |
michael@0 | 406 | #define CERTDB_USER (1u<<6) |
michael@0 | 407 | #define CERTDB_TRUSTED_CLIENT_CA (1u<<7) /* trusted for issuing client certs */ |
michael@0 | 408 | #define CERTDB_INVISIBLE_CA (1u<<8) /* don't show in UI */ |
michael@0 | 409 | #define CERTDB_GOVT_APPROVED_CA (1u<<9) /* can do strong crypto in export ver */ |
michael@0 | 410 | #define CERTDB_MUST_VERIFY (1u<<10) /* explicitly don't trust this cert */ |
michael@0 | 411 | #define CERTDB_TRUSTED_UNKNOWN (1u<<11) /* accept trust from another source */ |
michael@0 | 412 | |
michael@0 | 413 | /* bits not affected by the CKO_NETSCAPE_TRUST object */ |
michael@0 | 414 | #define CERTDB_PRESERVE_TRUST_BITS (CERTDB_USER | \ |
michael@0 | 415 | CERTDB_NS_TRUSTED_CA | CERTDB_VALID_CA | CERTDB_INVISIBLE_CA | \ |
michael@0 | 416 | CERTDB_GOVT_APPROVED_CA) |
michael@0 | 417 | |
michael@0 | 418 | #endif /* _PCERTT_H_ */ |