1 /*
2  *
3  *  Copyright (C) 1998-2019, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module: dcmsign
15  *
16  *  Author: Marco Eichelberg
17  *
18  *  Purpose:
19  *    classes: SiCertificateVerifier
20  *
21  */
22 
23 #ifndef SICERTVF_H
24 #define SICERTVF_H
25 
26 #include "dcmtk/config/osconfig.h"
27 
28 #ifdef WITH_OPENSSL
29 
30 #include "dcmtk/dcmsign/sitypes.h"
31 
32 class SiCertificate;
33 struct x509_store_st;
34 struct x509_store_ctx_st;
35 struct stack_st_X509; // this is STACK_OF(X509) in OpenSSL
36 typedef struct x509_store_st X509_STORE;
37 typedef struct x509_store_ctx_st X509_STORE_CTX;
38 
39 /** a class representing X.509 public key certificates.
40  *  @remark this class is only available if DCMTK is compiled with
41  *  OpenSSL support enabled.
42  */
43 class DCMTK_DCMSIGN_EXPORT SiCertificateVerifier
44 {
45 public:
46 
47   /// default constructor
48   SiCertificateVerifier();
49 
50   ///destructor
51   virtual ~SiCertificateVerifier();
52 
53   /** loads a certificate from a file and adds it to the pool of trusted certificates.
54    *  @param fileName path to the certificate file
55    *  @param filetype file format: X509_FILETYPE_PEM or X509_FILETYPE_ASN1
56    *  @return SI_EC_Normal if successful, an error code otherwise
57    */
58   virtual OFCondition addTrustedCertificateFile(const char *fileName, int fileType);
59 
60   /** loads an untrusted certificate from a file and adds it to the pool
61    *  of untrusted certificates. During certificate verification these will
62    *  only be accepted as intermediate CAs (not as root CA) and will undergo
63    *  additional scrutiny (e.g. check of the purpose extension, if present).
64    *  @param fileName path to the certificate file
65    *  @param filetype file format: X509_FILETYPE_PEM or X509_FILETYPE_ASN1
66    *  @return SI_EC_Normal if successful, an error code otherwise
67    */
68   virtual OFCondition addUntrustedCertificateFile(const char *fileName, int fileType);
69 
70   /** loads all files as certificates from the specified directory and adds them
71    *  to the pool of trusted certificates.
72    *  @param fileName path to the directory containing certificate files
73    *  @param filetype file format: X509_FILETYPE_PEM or X509_FILETYPE_ASN1
74    *  @return SI_EC_Normal if successful, an error code otherwise
75    */
76   virtual OFCondition addTrustedCertificateDir(const char *pathName, int fileType);
77 
78   /** loads a certificate revocation list (CRL) in X.509 format from a file and
79    *  adds it to the pool of trusted certificates and CRLs.
80    *  @param fileName path to the CRL file
81    *  @param filetype file format: X509_FILETYPE_PEM or X509_FILETYPE_ASN1
82    *  @return SI_EC_Normal if successful, an error code otherwise
83    */
84   virtual OFCondition addCertificateRevocationList(const char *fileName, int fileType);
85 
86   /** verifies a certificate against the known trusted CA certificates
87    *  and certificate revocation lists. Returns a status flag and stores
88    *  a detailed error description that can be retrieved with lastError().
89    *  @param certificate the certificate to verify
90    *  @return SI_EC_Normal if successful, an error code otherwise.
91    *     If the certificate could not be verified, returns SI_EC_VerificationFailed_NoTrust.
92    */
93   virtual OFCondition verifyCertificate(SiCertificate& certificate);
94 
95   /** returns an error string containing a textual description of the result
96    *  of the last call to verifyCertificate() if that call returned
97    *  SI_EC_VerificationFailed_NoTrust.
98    *  @return text string
99    */
100   virtual const char *lastError() const;
101 
102   /** returns true if the result of the last call to verifyCertificate()
103    *  was the status code indicating that the certificate has expired,
104    *  false otherwise
105    *  @return true if verifyCertificate() reported certificate expiry.
106    */
107   virtual OFBool lastErrorIsCertExpiry() const;
108 
109   /** returns a pointer to the trusted certificate store managed by this object.
110    *  @return pointer to trusted certificate store
111    */
112   virtual X509_STORE *getTrustedCertStore();
113 
114   /** returns a pointer to the stack of untrusted certificates managed by this object.
115    *  Note that the return type is equivalent to OpenSSL's STACK_OF(X509).
116    *  @return pointer to stack of untrusted certificates
117    */
118   virtual stack_st_X509 *getUntrustedCerts();
119 
120   /** enable or disable the verification of certificate revocation lists.
121    *  When enabled, a CRL is expected to be present for every CA certificate,
122    *  and certificate verification will fail if no CRL is found.
123    *  @param enabled OFTrue to enable verification, OFFalse to disable
124    */
125   virtual void setCRLverification(OFBool enabled);
126 
127   /** Callback function for certificate verification operations.
128    *  This method can be used by derived classes to examine and modify the
129    * result of a certificate verification.
130    *  @param deflt default return code that should be returned if the callback does
131    *    not modify the result of the verification
132    *  @param ctx certificate verification context object
133    *  @return result of the verification, 0 for error, 1 for no error, 2 for "policy checking complete".
134    */
135   virtual int verifyCallback(int deflt, X509_STORE_CTX *ctx);
136 
137 private:
138 
139   /// private undefined copy constructor
140   SiCertificateVerifier(SiCertificateVerifier& arg);
141 
142   /// private undefined copy assignment operator
143   SiCertificateVerifier& operator=(SiCertificateVerifier& arg);
144 
145   /// OpenSSL X.509 certificate store
146   X509_STORE *x509store;
147 
148   /// OpenSSL X.509 stack of untrusted intermediate certificates
149   stack_st_X509 *x509untrusted;
150 
151   /// flag indicating whether CRL verification should be enabled
152   OFBool enableCRLverification;
153 
154   /// OpenSSL X.509 certificate verification error code for the last operation
155   long errorCode;
156 
157 };
158 
159 #endif
160 #endif
161 
162