Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

"""Tests for ocsp.py""" 

# pylint: disable=protected-access 

 

import unittest 

 

import mock 

 

from certbot import errors 

 

out = """Missing = in header key=value 

ocsp: Use -help for summary. 

""" 

 

class OCSPTest(unittest.TestCase): 

 

 

def setUp(self): 

from certbot import ocsp 

with mock.patch('certbot.ocsp.Popen') as mock_popen: 

with mock.patch('certbot.util.exe_exists') as mock_exists: 

mock_communicate = mock.MagicMock() 

mock_communicate.communicate.return_value = (None, out) 

mock_popen.return_value = mock_communicate 

mock_exists.return_value = True 

self.checker = ocsp.RevocationChecker() 

 

def tearDown(self): 

pass 

 

@mock.patch('certbot.ocsp.logger.info') 

@mock.patch('certbot.ocsp.Popen') 

@mock.patch('certbot.util.exe_exists') 

def test_init(self, mock_exists, mock_popen, mock_log): 

mock_communicate = mock.MagicMock() 

mock_communicate.communicate.return_value = (None, out) 

mock_popen.return_value = mock_communicate 

mock_exists.return_value = True 

 

from certbot import ocsp 

checker = ocsp.RevocationChecker() 

self.assertEqual(mock_popen.call_count, 1) 

self.assertEqual(checker.host_args("x"), ["Host=x"]) 

 

mock_communicate.communicate.return_value = (None, out.partition("\n")[2]) 

checker = ocsp.RevocationChecker() 

self.assertEqual(checker.host_args("x"), ["Host", "x"]) 

self.assertEqual(checker.broken, False) 

 

mock_exists.return_value = False 

mock_popen.call_count = 0 

checker = ocsp.RevocationChecker() 

self.assertEqual(mock_popen.call_count, 0) 

self.assertEqual(mock_log.call_count, 1) 

self.assertEqual(checker.broken, True) 

 

@mock.patch('certbot.ocsp.RevocationChecker.determine_ocsp_server') 

@mock.patch('certbot.util.run_script') 

def test_ocsp_revoked(self, mock_run, mock_determine): 

self.checker.broken = True 

mock_determine.return_value = ("", "") 

self.assertEqual(self.checker.ocsp_revoked("x", "y"), False) 

 

self.checker.broken = False 

mock_run.return_value = tuple(openssl_happy[1:]) 

self.assertEqual(self.checker.ocsp_revoked("x", "y"), False) 

self.assertEqual(mock_run.call_count, 0) 

 

mock_determine.return_value = ("http://x.co", "x.co") 

self.assertEqual(self.checker.ocsp_revoked("blah.pem", "chain.pem"), False) 

mock_run.side_effect = errors.SubprocessError("Unable to load certificate launcher") 

self.assertEqual(self.checker.ocsp_revoked("x", "y"), False) 

self.assertEqual(mock_run.call_count, 2) 

 

 

@mock.patch('certbot.ocsp.logger.info') 

@mock.patch('certbot.util.run_script') 

def test_determine_ocsp_server(self, mock_run, mock_info): 

uri = "http://ocsp.stg-int-x1.letsencrypt.org/" 

host = "ocsp.stg-int-x1.letsencrypt.org" 

mock_run.return_value = uri, "" 

self.assertEqual(self.checker.determine_ocsp_server("beep"), (uri, host)) 

mock_run.return_value = "ftp:/" + host + "/", "" 

self.assertEqual(self.checker.determine_ocsp_server("beep"), (None, None)) 

self.assertEqual(mock_info.call_count, 1) 

 

c = "confusion" 

mock_run.side_effect = errors.SubprocessError(c) 

self.assertEqual(self.checker.determine_ocsp_server("beep"), (None, None)) 

 

@mock.patch('certbot.ocsp.logger') 

@mock.patch('certbot.util.run_script') 

def test_translate_ocsp(self, mock_run, mock_log): 

# pylint: disable=protected-access,star-args 

mock_run.return_value = openssl_confused 

from certbot import ocsp 

self.assertEqual(ocsp._translate_ocsp_query(*openssl_happy), False) 

self.assertEqual(ocsp._translate_ocsp_query(*openssl_confused), False) 

self.assertEqual(mock_log.debug.call_count, 1) 

self.assertEqual(mock_log.warning.call_count, 0) 

mock_log.debug.call_count = 0 

self.assertEqual(ocsp._translate_ocsp_query(*openssl_unknown), False) 

self.assertEqual(mock_log.debug.call_count, 1) 

self.assertEqual(mock_log.warning.call_count, 0) 

self.assertEqual(ocsp._translate_ocsp_query(*openssl_expired_ocsp), False) 

self.assertEqual(mock_log.debug.call_count, 2) 

self.assertEqual(ocsp._translate_ocsp_query(*openssl_broken), False) 

self.assertEqual(mock_log.warning.call_count, 1) 

mock_log.info.call_count = 0 

self.assertEqual(ocsp._translate_ocsp_query(*openssl_revoked), True) 

self.assertEqual(mock_log.info.call_count, 0) 

self.assertEqual(ocsp._translate_ocsp_query(*openssl_expired_ocsp_revoked), True) 

self.assertEqual(mock_log.info.call_count, 1) 

 

 

# pylint: disable=line-too-long 

openssl_confused = ("", """ 

/etc/letsencrypt/live/example.org/cert.pem: good 

This Update: Dec 17 00:00:00 2016 GMT 

Next Update: Dec 24 00:00:00 2016 GMT 

""", 

""" 

Response Verify Failure 

139903674214048:error:27069065:OCSP routines:OCSP_basic_verify:certificate verify error:ocsp_vfy.c:138:Verify error:unable to get local issuer certificate 

""") 

 

openssl_happy = ("blah.pem", """ 

blah.pem: good 

This Update: Dec 20 18:00:00 2016 GMT 

Next Update: Dec 27 18:00:00 2016 GMT 

""", 

"Response verify OK") 

 

openssl_revoked = ("blah.pem", """ 

blah.pem: revoked 

This Update: Dec 20 01:00:00 2016 GMT 

Next Update: Dec 27 01:00:00 2016 GMT 

Revocation Time: Dec 20 01:46:34 2016 GMT 

""", 

"""Response verify OK""") 

 

openssl_unknown = ("blah.pem", """ 

blah.pem: unknown 

This Update: Dec 20 18:00:00 2016 GMT 

Next Update: Dec 27 18:00:00 2016 GMT 

""", 

"Response verify OK") 

 

openssl_broken = ("", "tentacles", "Response verify OK") 

 

openssl_expired_ocsp = ("blah.pem", """ 

blah.pem: WARNING: Status times invalid. 

140659132298912:error:2707307D:OCSP routines:OCSP_check_validity:status expired:ocsp_cl.c:372: 

good 

This Update: Apr 6 00:00:00 2016 GMT 

Next Update: Apr 13 00:00:00 2016 GMT 

""", 

"""Response verify OK""") 

 

openssl_expired_ocsp_revoked = ("blah.pem", """ 

blah.pem: WARNING: Status times invalid. 

140659132298912:error:2707307D:OCSP routines:OCSP_check_validity:status expired:ocsp_cl.c:372: 

revoked 

This Update: Apr 6 00:00:00 2016 GMT 

Next Update: Apr 13 00:00:00 2016 GMT 

""", 

"""Response verify OK""") 

 

if __name__ == '__main__': 

unittest.main() # pragma: no cover