File: X509.h

package info (click to toggle)
bro 2.5.5-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, sid
  • size: 79,416 kB
  • sloc: ansic: 129,203; cpp: 96,492; yacc: 2,528; lex: 1,819; sh: 795; python: 700; makefile: 136
file content (144 lines) | stat: -rw-r--r-- 3,422 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// See the file "COPYING" in the main distribution directory for copyright.

#ifndef FILE_ANALYSIS_X509_H
#define FILE_ANALYSIS_X509_H

#include <string>

#include "Val.h"
#include "../File.h"
#include "Analyzer.h"

#include <openssl/x509.h>
#include <openssl/asn1.h>

#if (OPENSSL_VERSION_NUMBER < 0x1010000fL)

#define EVP_PKEY_get0_DSA(p)    ((p)->pkey.dsa)
#define EVP_PKEY_get0_EC_KEY(p) ((p)->pkey.ec)
#define EVP_PKEY_get0_RSA(p)    ((p)->pkey.rsa)

static void DSA_get0_pqg(const DSA *d,
                  const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
{
    if (p != NULL)
        *p = d->p;
    if (q != NULL)
        *q = d->q;
    if (g != NULL)
        *g = d->g;
}

static void RSA_get0_key(const RSA *r,
                  const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
{
    if (n != NULL)
        *n = r->n;
    if (e != NULL)
        *e = r->e;
    if (d != NULL)
        *d = r->d;
}
#endif

namespace file_analysis {

class X509Val;

class X509 : public file_analysis::Analyzer {
public:
	virtual bool DeliverStream(const u_char* data, uint64 len);
	virtual bool Undelivered(uint64 offset, uint64 len);
	virtual bool EndOfFile();

	/**
	 * Converts an X509 certificate into a \c X509::Certificate record
	 * value. This is a static function that can be called from external,
	 * it doesn't depend on the state of any particular file analyzer.
	 *
	 * @param cert_val The certificate to converts.
	 *
	 * @param fid A file ID associated with the certificate, if any
	 * (primarily for error reporting).
	 *
	 * @param Returns the new record value and passes ownership to
	 * caller.
	 */
	static RecordVal* ParseCertificate(X509Val* cert_val, const char* fid = 0);

	static file_analysis::Analyzer* Instantiate(RecordVal* args, File* file)
		{ return new X509(args, file); }

	/**
	 * Retrieve an X509 extension value from an OpenSSL BIO to which it was
	 * written.
	 *
	 * @param bio the OpenSSL BIO to read. It will be freed by the function,
	 * including when an error occurs.
	 *
	 * @return The X509 extension value.
	 */
	static StringVal* GetExtensionFromBIO(BIO* bio);

protected:
	X509(RecordVal* args, File* file);

private:
	void ParseExtension(X509_EXTENSION* ex);
	void ParseBasicConstraints(X509_EXTENSION* ex);
	void ParseSAN(X509_EXTENSION* ex);

	std::string cert_data;

	// Helpers for ParseCertificate.
	static double GetTimeFromAsn1(const ASN1_TIME * atime, const char* fid);
	static StringVal* KeyCurve(EVP_PKEY *key);
	static unsigned int KeyLength(EVP_PKEY *key);
};

/**
 * This class wraps an OpenSSL X509 data structure.
 *
 * We need these to be able to pass OpenSSL pointers around in Bro
 * script-land. Otherwise, we cannot verify certificates from Bro
 * scriptland
 */
class X509Val : public OpaqueVal {
public:
	/**
	 * Construct an X509Val.
	 *
	 * @param certificate specifies the wrapped OpenSSL certificate
	 *
	 * @return A newly initialized X509Val.
	 */
	explicit X509Val(::X509* certificate);

	/**
	 * Destructor.
	 */
	~X509Val();

	/**
	 * Get the wrapped X509 certificate. Please take care, that the
	 * internal OpenSSL reference counting stays the same.
	 *
	 * @return The wrapped OpenSSL X509 certificate.
	 */
	::X509* GetCertificate() const;

protected:
	/**
	 * Construct an empty X509Val. Only used for deserialization
	 */
	X509Val();

private:
	::X509* certificate; // the wrapped certificate

	DECLARE_SERIAL(X509Val);
};

}

#endif