Add CLI usage for pki.py and update Makefile (#254)
* Add CLI usage for pki.py * Bump to 2.1.0 * Replace direct openssl invocation with pki utility * Bolder * Ordering and version in README * Refine help
This commit is contained in:
parent
067664e6ed
commit
ac29e34137
|
@ -18,6 +18,7 @@ proxy.py.iml
|
|||
*.csr
|
||||
*.crt
|
||||
*.key
|
||||
*.pem
|
||||
venv*
|
||||
|
||||
cover
|
||||
|
|
23
Makefile
23
Makefile
|
@ -30,18 +30,31 @@ autopep8:
|
|||
|
||||
https-certificates:
|
||||
# Generate server key
|
||||
openssl genrsa -out $(HTTPS_KEY_FILE_PATH) 2048
|
||||
python -m proxy.common.pki gen_private_key \
|
||||
--private-key-path $(HTTPS_KEY_FILE_PATH)
|
||||
python -m proxy.common.pki remove_passphrase \
|
||||
--private-key-path $(HTTPS_KEY_FILE_PATH)
|
||||
# Generate server certificate
|
||||
openssl req -new -x509 -days 3650 -key $(HTTPS_KEY_FILE_PATH) -out $(HTTPS_CERT_FILE_PATH)
|
||||
python -m proxy.common.pki gen_public_key \
|
||||
--private-key-path $(HTTPS_KEY_FILE_PATH) \
|
||||
--public-key-path $(HTTPS_CERT_FILE_PATH)
|
||||
|
||||
ca-certificates:
|
||||
# Generate CA key
|
||||
openssl genrsa -out $(CA_KEY_FILE_PATH) 2048
|
||||
python -m proxy.common.pki gen_private_key \
|
||||
--private-key-path $(CA_KEY_FILE_PATH)
|
||||
python -m proxy.common.pki remove_passphrase \
|
||||
--private-key-path $(CA_KEY_FILE_PATH)
|
||||
# Generate CA certificate
|
||||
openssl req -new -x509 -days 3650 -key $(CA_KEY_FILE_PATH) -out $(CA_CERT_FILE_PATH)
|
||||
python -m proxy.common.pki gen_public_key \
|
||||
--private-key-path $(CA_KEY_FILE_PATH) \
|
||||
--public-key-path $(CA_CERT_FILE_PATH)
|
||||
# Generate key that will be used to generate domain certificates on the fly
|
||||
# Generated certificates are then signed with CA certificate / key generated above
|
||||
openssl genrsa -out $(CA_SIGNING_KEY_FILE_PATH) 2048
|
||||
python -m proxy.common.pki gen_private_key \
|
||||
--private-key-path $(CA_SIGNING_KEY_FILE_PATH)
|
||||
python -m proxy.common.pki remove_passphrase \
|
||||
--private-key-path $(CA_SIGNING_KEY_FILE_PATH)
|
||||
|
||||
lib-clean:
|
||||
find . -name '*.pyc' -exec rm -f {} +
|
||||
|
|
66
README.md
66
README.md
|
@ -88,9 +88,9 @@ Table of Contents
|
|||
* [Http](#http-client)
|
||||
* [build_http_request](#build_http_request)
|
||||
* [build_http_response](#build_http_response)
|
||||
* [Websocket](#websocket)
|
||||
* [WebsocketFrame](#websocketframe)
|
||||
* [WebsocketClient](#websocketclient)
|
||||
* [Public Key Infrastructure](#pki)
|
||||
* [API Usage](#api-usage)
|
||||
* [CLI Usage](#cli-usage)
|
||||
* [Frequently Asked Questions](#frequently-asked-questions)
|
||||
* [SyntaxError: invalid syntax](#syntaxerror-invalid-syntax)
|
||||
* [Unable to load plugins](#unable-to-load-plugins)
|
||||
|
@ -1161,7 +1161,7 @@ Utilities
|
|||
|
||||
## TCP Sockets
|
||||
|
||||
#### new_socket_connection
|
||||
### new_socket_connection
|
||||
|
||||
Attempts to create an IPv4 connection, then IPv6 and
|
||||
finally a dual stack connection to provided address.
|
||||
|
@ -1172,7 +1172,7 @@ finally a dual stack connection to provided address.
|
|||
>>> conn.close()
|
||||
```
|
||||
|
||||
#### socket_connection
|
||||
### socket_connection
|
||||
|
||||
`socket_connection` is a convenient decorator + context manager
|
||||
around `new_socket_connection` which ensures `conn.close` is implicit.
|
||||
|
@ -1194,9 +1194,9 @@ As a decorator:
|
|||
|
||||
## Http Client
|
||||
|
||||
#### build_http_request
|
||||
### build_http_request
|
||||
|
||||
##### Generate HTTP GET request
|
||||
#### Generate HTTP GET request
|
||||
|
||||
```python
|
||||
>>> build_http_request(b'GET', b'/')
|
||||
|
@ -1204,7 +1204,7 @@ b'GET / HTTP/1.1\r\n\r\n'
|
|||
>>>
|
||||
```
|
||||
|
||||
##### Generate HTTP GET request with headers
|
||||
#### Generate HTTP GET request with headers
|
||||
|
||||
```python
|
||||
>>> build_http_request(b'GET', b'/',
|
||||
|
@ -1213,7 +1213,7 @@ b'GET / HTTP/1.1\r\nConnection: close\r\n\r\n'
|
|||
>>>
|
||||
```
|
||||
|
||||
##### Generate HTTP POST request with headers and body
|
||||
#### Generate HTTP POST request with headers and body
|
||||
|
||||
```python
|
||||
>>> import json
|
||||
|
@ -1223,19 +1223,53 @@ b'GET / HTTP/1.1\r\nConnection: close\r\n\r\n'
|
|||
b'POST /form HTTP/1.1\r\nContent-type: application/json\r\n\r\n{"email": "hello@world.com"}'
|
||||
```
|
||||
|
||||
#### build_http_response
|
||||
### build_http_response
|
||||
|
||||
TODO
|
||||
|
||||
## Websocket
|
||||
## PKI
|
||||
|
||||
#### WebsocketFrame
|
||||
### API Usage
|
||||
|
||||
TODO
|
||||
#### gen_private_key
|
||||
#### gen_public_key
|
||||
#### remove_passphrase
|
||||
#### gen_csr
|
||||
#### sign_csr
|
||||
|
||||
#### WebsocketClient
|
||||
See [pki.py](https://github.com/abhinavsingh/proxy.py/blob/develop/proxy/common/pki.py) are
|
||||
method definitions.
|
||||
|
||||
TODO
|
||||
### CLI Usage
|
||||
|
||||
Use `proxy.common.pki` module for:
|
||||
|
||||
1) Generation of public and private keys
|
||||
2) Generating CSR requests
|
||||
3) Signing CSR requests using custom CA.
|
||||
|
||||
```bash
|
||||
python -m proxy.common.pki -h
|
||||
usage: pki.py [-h] [--password PASSWORD] [--private-key-path PRIVATE_KEY_PATH]
|
||||
[--public-key-path PUBLIC_KEY_PATH] [--subject SUBJECT]
|
||||
action
|
||||
|
||||
proxy.py v2.1.0 : PKI Utility
|
||||
|
||||
positional arguments:
|
||||
action Valid actions: remove_passphrase, gen_private_key,
|
||||
gen_public_key, gen_csr, sign_csr
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
--password PASSWORD Password to use for encryption. Default: proxy.py
|
||||
--private-key-path PRIVATE_KEY_PATH
|
||||
Private key path
|
||||
--public-key-path PUBLIC_KEY_PATH
|
||||
Public key path
|
||||
--subject SUBJECT Subject to use for public key generation. Default:
|
||||
/CN=example.com
|
||||
```
|
||||
|
||||
## Internal Documentation
|
||||
|
||||
|
@ -1377,7 +1411,7 @@ usage: proxy [-h] [--backlog BACKLOG] [--basic-auth BASIC_AUTH]
|
|||
[--static-server-dir STATIC_SERVER_DIR] [--threadless]
|
||||
[--timeout TIMEOUT] [--version]
|
||||
|
||||
proxy.py v2.0.0
|
||||
proxy.py v2.1.0
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
:copyright: (c) 2013-present by Abhinav Singh and contributors.
|
||||
:license: BSD, see LICENSE for more details.
|
||||
"""
|
||||
import sys
|
||||
import argparse
|
||||
import contextlib
|
||||
import os
|
||||
import uuid
|
||||
|
@ -18,6 +20,7 @@ from typing import List, Generator, Optional, Tuple
|
|||
|
||||
from .utils import bytes_
|
||||
from .constants import COMMA
|
||||
from .version import __version__
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -212,3 +215,68 @@ def run_openssl_command(command: List[str], timeout: int) -> bool:
|
|||
)
|
||||
cmd.communicate(timeout=timeout)
|
||||
return cmd.returncode == 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
available_actions = (
|
||||
'remove_passphrase', 'gen_private_key', 'gen_public_key',
|
||||
'gen_csr', 'sign_csr'
|
||||
)
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='proxy.py v%s : PKI Utility' % __version__,
|
||||
)
|
||||
parser.add_argument(
|
||||
'action',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Valid actions: ' + ', '.join(available_actions)
|
||||
)
|
||||
parser.add_argument(
|
||||
'--password',
|
||||
type=str,
|
||||
default='proxy.py',
|
||||
help='Password to use for encryption. Default: proxy.py',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--private-key-path',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Private key path',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--public-key-path',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Public key path',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--subject',
|
||||
type=str,
|
||||
default='/CN=example.com',
|
||||
help='Subject to use for public key generation. Default: /CN=example.com',
|
||||
)
|
||||
args = parser.parse_args(sys.argv[1:])
|
||||
|
||||
# Validation
|
||||
if args.action not in available_actions:
|
||||
print('Invalid --action. Valid values ' + ', '.join(available_actions))
|
||||
sys.exit(1)
|
||||
if args.action in ('gen_private_key', 'gen_public_key'):
|
||||
if args.private_key_path is None:
|
||||
print('--private-key-path is required for ' + args.action)
|
||||
sys.exit(1)
|
||||
if args.action == 'gen_public_key':
|
||||
if args.public_key_path is None:
|
||||
print('--public-key-file is required for private key generation')
|
||||
sys.exit(1)
|
||||
|
||||
# Execute
|
||||
if args.action == 'gen_private_key':
|
||||
gen_private_key(args.private_key_path, args.password)
|
||||
elif args.action == 'gen_public_key':
|
||||
gen_public_key(args.public_key_path, args.private_key_path,
|
||||
args.password, args.subject)
|
||||
elif args.action == 'remove_passphrase':
|
||||
remove_passphrase(args.private_key_path, args.password,
|
||||
args.private_key_path)
|
||||
|
|
|
@ -8,5 +8,5 @@
|
|||
:copyright: (c) 2013-present by Abhinav Singh and contributors.
|
||||
:license: BSD, see LICENSE for more details.
|
||||
"""
|
||||
VERSION = (2, 0, 0)
|
||||
VERSION = (2, 1, 0)
|
||||
__version__ = '.'.join(map(str, VERSION[0:3]))
|
||||
|
|
Loading…
Reference in New Issue