Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CT Log List and deprecation warnings #20

Closed
wants to merge 11 commits into from
Closed
Binary file added .DS_Store
Binary file not shown.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pip3 install axeman
```
$ axeman -h
usage: axeman [-h] [-f LOG_FILE] [-s START_OFFSET] [-l] [-u CTL_URL]
[-o OUTPUT_DIR] [-v] [-c CONCURRENCY_COUNT]
[-z CTL_OFFSET] [-o OUTPUT_DIR] [-v] [-c CONCURRENCY_COUNT]

Pull down certificate transparency list information

Expand All @@ -29,9 +29,11 @@ optional arguments:
-s START_OFFSET Skip N number of lists before starting
-l List all available certificate lists
-u CTL_URL Retrieve this CTL only
-z CTL_OFFSET The CTL offset to start at
-o OUTPUT_DIR The output directory to store certificates in
-v Print out verbose/debug info
-c CONCURRENCY_COUNT The number of concurrent downloads to run at a time

```

## Demo
Expand Down
2 changes: 1 addition & 1 deletion axeman/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '1.14'
__version__ = '1.15'

if __name__ == "__main__":
from .core import main
Expand Down
20 changes: 11 additions & 9 deletions axeman/certlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

from OpenSSL import crypto

CTL_LISTS = 'https://www.gstatic.com/ct/log_list/log_list.json'
CTL_LISTS = 'https://www.gstatic.com/ct/log_list/v2/log_list.json'

CTL_INFO = "http://{}/ct/v1/get-sth"
CTL_INFO = "{}/ct/v1/get-sth"

DOWNLOAD = "http://{}/ct/v1/get-entries?start={}&end={}"
DOWNLOAD = "{}/ct/v1/get-entries?start={}&end={}"

from construct import Struct, Byte, Int16ub, Int64ub, Enum, Bytes, Int24ub, this, GreedyBytes, GreedyRange, Terminated, Embedded

Expand Down Expand Up @@ -42,13 +42,15 @@ async def retrieve_all_ctls(session=None):
async with session.get(CTL_LISTS) as response:
ctl_lists = await response.json()

logs = ctl_lists['logs']
operators = ctl_lists['operators']

for log in logs:
if log['url'].endswith('/'):
log['url'] = log['url'][:-1]
owner = _get_owner(log, ctl_lists['operators'])
log['operated_by'] = owner
logs = list()
for operator in operators:
for log in operator['logs']:
if log['url'].endswith('/'):
log['url'] = log['url'][:-1]
log['operated_by'] = operator['name']
logs.append(log)

return logs

Expand Down
29 changes: 18 additions & 11 deletions axeman/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

import sys
import time
import json
import math
import base64
import os
Expand Down Expand Up @@ -37,6 +39,7 @@ async def download_worker(session, log_info, work_deque, download_queue):

logging.debug("[{}] Queueing up blocks {}-{}...".format(log_info['url'], start, end))


for x in range(3):
try:
async with session.get(certlib.DOWNLOAD.format(log_info['url'], start, end)) as response:
Expand Down Expand Up @@ -74,7 +77,7 @@ async def queue_monitor(log_info, work_deque, download_results_queue):
await asyncio.sleep(2)

async def retrieve_certificates(loop, url=None, ctl_offset=0, output_directory='/tmp/', concurrency_count=DOWNLOAD_CONCURRENCY):
async with aiohttp.ClientSession(loop=loop, conn_timeout=10) as session:
async with aiohttp.ClientSession(loop=loop, timeout = aiohttp.ClientTimeout(total=10)) as session:
ctl_logs = await certlib.retrieve_all_ctls(session)

if url:
Expand Down Expand Up @@ -143,9 +146,8 @@ async def processing_coro(download_results_queue, output_dir="/tmp"):

logging.debug("Got a chunk of {}. Mapping into process pool".format(process_pool.pool_workers))


for entry in entries_iter:
csv_storage = '{}/certificates/{}'.format(output_dir, entry['log_info']['url'].replace('/', '_'))
csv_storage = '{}/certificates/{}'.format(output_dir, entry['log_info']['url'].replace('https://', ''))
if not os.path.exists(csv_storage):
print("[{}] Making dir...".format(os.getpid()))
os.makedirs(csv_storage)
Expand Down Expand Up @@ -236,20 +238,24 @@ def process_worker(result_info):
return True

async def get_certs_and_print():
async with aiohttp.ClientSession(conn_timeout=5) as session:
async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=5)) as session:
ctls = await certlib.retrieve_all_ctls(session)
print("Found {} CTLs...".format(len(ctls)))
output = []
for log in ctls:
try:
log_info = await certlib.retrieve_log_info(log, session)
except:
continue

print(log['description'])
print(" \- URL: {}".format(log['url']))
print(" \- Owner: {}".format(log_info['operated_by']))
print(" \- Cert Count: {}".format(locale.format("%d", log_info['tree_size']-1, grouping=True)))
print(" \- Max Block Size: {}\n".format(log_info['block_size']))
output.append({
"description": log['description'],
"url": log['url'],
"owner": log_info['operated_by'],
"cert_count": log_info['tree_size']-1,
"max_block_size": log_info['block_size']
})

print(json.dumps(output, indent=4))

def main():
loop = asyncio.get_event_loop()
Expand All @@ -272,7 +278,8 @@ def main():

parser.add_argument('-v', dest="verbose", action="store_true", help="Print out verbose/debug info")

parser.add_argument('-c', dest='concurrency_count', action='store', default=50, type=int, help="The number of concurrent downloads to run at a time")
parser.add_argument('-c', dest='concurrency_count', action='store', default=DOWNLOAD_CONCURRENCY, type=int,
help="The number of concurrent downloads to run at a time, default "+str(DOWNLOAD_CONCURRENCY))

args = parser.parse_args()

Expand Down