i need to create a CSR with specific configuration using python
this is my configuration :
oid_section = OIDs
[ OIDs ]
certificateTemplateName= 1.3.6.1.4.1.311.20.2
[ req ]
default_bits = 2048
emailAddress = test#gmail.com
req_extensions = v3_req
x509_extensions = v3_ca
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
C=SA
OU=3111111117
O=shesh
CN = tat-1
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment
[req_ext]
certificateTemplateName = ASN1:PRINTABLESTRING:PREZATCA-Code-Signing
subjectAltName = dirName:alt_names
[alt_names]
SN=1-Device|2-234|3-mohamm
UID=30000000000000003
title=1000
registeredAddress=Zatca 12
businessCategory=Technology
i can create a CSR with this configuration using OpenSSL
but i need to Create a CSR with this configuration using Python.
i tried to do it using this code:
from OpenSSL.SSL import FILETYPE_PEM
from OpenSSL.crypto import dump_certificate_request, dump_privatekey,dump_publickey, PKey, TYPE_DSA, X509Req
# create public/private key
key = PKey()
key.generate_key(TYPE_DSA,1028)
print(key.to_cryptography_key())
# Generate CSR
req = X509Req()
req.get_subject().CN = 'localhost'
req.get_subject().O = 'XYZ Widgets Inc'
req.get_subject().OU = 'IT Department'
req.get_subject().L = 'Seattle'
req.get_subject().ST = 'Washington'
req.get_subject().C = 'US'
req.get_subject().emailAddress = 'e#example.com'
req.set_pubkey(key)
req.sign(key, 'sha256')
with open("csr_testo.pem", 'wb+') as f:
f.write(dump_certificate_request(FILETYPE_PEM, req))
with open("Private_key_testo.pem", 'wb+') as f:
f.write(dump_privatekey(FILETYPE_PEM, key))
with open("public_key_testo.pem", 'wb+') as f:
f.write(dump_publickey(FILETYPE_PEM, key))
but it does not take all of my configuration.
[alt_names]
SN=1-Device|2-234|3-mohamm
UID=30000000000000003
title=1000
registeredAddress=Zatca 12
businessCategory=Technology
these configurations are very important to include them in the CSR
Please try this code
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import dsa
from cryptography.x509.oid import NameOID, ExtensionOID
# Generate a private key
private_key = dsa.generate_private_key(key_size=2048)
# Set the subject name and add extensions
subject = x509.Name([
x509.NameAttribute(NameOID.COUNTRY_NAME, "SA"),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, "shesh"),
x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "3111111117"),
x509.NameAttribute(NameOID.COMMON_NAME, "tat-1"),
])
extensions = [
x509.BasicConstraints(ca=False, path_length=None),
x509.KeyUsage(digital_signature=True, key_encipherment=True, content_commitment=False, data_encipherment=False, key_agreement=False, encipher_only=False, decipher_only=False),
x509.SubjectAlternativeName([
x509.DirectoryName(x509.Name([
x509.NameAttribute(NameOID.SERIAL_NUMBER, "1-Device|2-234|3-mohamm"),
x509.NameAttribute(NameOID.USER_ID, "30000000000000003"),
x509.NameAttribute(NameOID.TITLE, "1000"),
x509.NameAttribute(NameOID.REGISTERED_ADDRESS, "Zatca 12"),
x509.NameAttribute(NameOID.BUSINESS_CATEGORY, "Technology"),
]))
]),
x509.CertificatePolicies([
x509.PolicyInformation(x509.ObjectIdentifier("1.3.6.1.4.1.311.20.2"), [])
])
]
# Generate the CSR
csr = x509.CertificateSigningRequestBuilder().subject_name(subject).add_extensions(extensions).sign(private_key, hashes.SHA256())
# Save the CSR and private key to files
with open("csr_testo.pem", "wb") as f:
f.write(csr.public_bytes(encoding=x509.Encoding.PEM))
with open("private_key_testo.pem", "wb") as f:
f.write(private_key.private_bytes(encoding=x509.Encoding.PEM, format=x509.PrivateFormat.PKCS8, encryption_algorithm=x509.NoEncryption()))
Related
I use the same protocol files, but I find that they have different output in Python and C++.
My protocol file:
namespace serial.proto.api.login;
table LoginReq {
account:string; //账号
passwd:string; //密码
device:string; //设备信息
token:string;
}
table LoginRsp {
account:string; //账号
passwd:string; //密码
device:string; //设备信息
token:string;
}
table LogoutReq {
account:string;
}
table LogoutRsp {
account:string;
}
My python code:
builder = flatbuffers.Builder()
account = builder.CreateString('test')
paswd = builder.CreateString('test')
device = builder.CreateString('test')
token = builder.CreateString('test')
LoginReq.LoginReqStart(builder)
LoginReq.LoginReqAddPasswd(builder, paswd)
LoginReq.LoginReqAddToken(builder, token)
LoginReq.LoginReqAddDevice(builder, device)
LoginReq.LoginReqAddAccount(builder, account)
login = LoginReq.LoginReqEnd(builder)
builder.Finish(login)
buf = builder.Output()
print(buf)
with open("layer.bin1","wb") as f:
f.write(buf)
My C++ code:
flatbuffers::FlatBufferBuilder builder;
auto account = builder.CreateString("test");
auto device = builder.CreateString("test");
auto passwd = builder.CreateString("test");
auto token = builder.CreateString("test");
auto l = CreateLoginReq(builder, account = account, passwd = passwd, device = device, token = token);
builder.Finish(l);
auto buf = builder.GetBufferPointer();
flatbuffers::SaveFile("layer.bin", reinterpret_cast<char *>(buf), builder.GetSize(), true);
output:
md5 layer.bin
MD5 (layer.bin) = 496e5031dda0f754fb4462fadce9e975
Flatbuffers generated by different implementations (i.e. generators) don't necessarily have the same binary layout, but can still be equivalent. It depends on how the implementation decide to write out the contents. So taking the hash of the binary is not going to tell you equivalence.
Some time ago I was working to rotate the password of the administrator#vsphere.local user in the Vcenter, but there isn't a lot of information about how to do that with Python. I did with LDAP protocol, I just want to create this to future references if someone need it.
import ldap
import os
import sys
vcenter = "the_IP_OR_Host_Name_of_the_VC"
ad_server = "ldap://"+vcenter
userAccount = 'Administrator'
ad_dn = "cn="+userAccount+",cn=users,dc=vsphere,dc=local"
username = 'CPMS_Test#vsphere.local'
old_pwd = 'The_Actual_PAss_of_Administrator'
new_pwd = 'New_Pass_of_the_Account'
# Lets initialize the LDAP, in our case is the same VC
l = ldap.initialize(ad_server)
#LDAP settings, Im not using SSL, but you can use it
l.protocol_version = ldap.VERSION3
l.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
l.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
l.simple_bind_s(ad_dn.format(username), old_pwd)
#lets run the update of the pass
password_value_old = old_pwd.encode("utf-8")
password_value = new_pwd.encode("utf-8")
mod_list = [
(ldap.MOD_DELETE, 'userpassword', [password_value_old]),
(ldap.MOD_ADD, 'userpassword', [password_value]),
]
result = l.modify_s(ad_dn.format(username), mod_list)
print(result.info)
I am using the "cryptography" module in Python to create self-signed certificates for testing.
I followed the examples here "https://cryptography.io/en/latest/x509/tutorial.html" and "https://gist.github.com/bloodearnest/9017111a313777b9cce5", and have the following code so far --
def generate_selfsigned_cert(hostname, san_list=None):
"""Generates self signed certificate for a hostname, and optional IP addresses."""
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from datetime import datetime
from datetime import timedelta
import ipaddress
# Generate pvt key
key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048
)
# Write key to file
pvt_key = self.log_directory + '/server.key.pem'
with open(pvt_key, 'wb') as f:
f.write(key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption(),
))
# Create cert
subject = issuer = x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, hostname),
x509.NameAttribute(NameOID.COUNTRY_NAME, 'X'),
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, 'X'),
x509.NameAttribute(NameOID.LOCALITY_NAME, 'X'),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'X'),
x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, 'X'),
x509.NameAttribute(NameOID.EMAIL_ADDRESS, 'X')
])
# best practice seem to be to include the hostname in the SAN, which *SHOULD* mean COMMON_NAME is ignored.
alt_names = [x509.DNSName(hostname)]
# allow addressing by IP, for when you don't have real DNS (common in most testing scenarios)
if san_list:
for addr in san_list:
# openssl wants DNSnames for ips...
alt_names.append(x509.DNSName(addr))
# ... whereas golang's crypto/tls is stricter, and needs IPAddresses
# note: older versions of cryptography do not understand ip_address objects
alt_names.append(x509.IPAddress(ipaddress.ip_address(addr)))
san = x509.SubjectAlternativeName(alt_names)
# path_len=0 means this cert can only sign itself, not other certs.
basic_contraints = x509.BasicConstraints(ca=True, path_length=0)
key_usage = x509.KeyUsage(digital_signature=True, key_encipherment=True, key_cert_sign=True,
key_agreement=False, content_commitment=False, data_encipherment=False,
crl_sign=False, encipher_only=False, decipher_only=False)
extended_key_usage = x509.ExtendedKeyUsage([x509.oid.ExtendedKeyUsageOID.SERVER_AUTH])
subject_key = x509.SubjectKeyIdentifier(digest=key.public_key())
authority_key = x509.AuthorityKeyIdentifier(key_identifier=key.public_key(), authority_cert_issuer=None, authority_cert_serial_number=None)**
cert = x509.CertificateBuilder()\
.subject_name(subject)\
.issuer_name(issuer)\
.public_key(key.public_key())\
.serial_number(x509.random_serial_number())\
.not_valid_before(datetime.utcnow())\
.not_valid_after(datetime.utcnow() + timedelta(days=10 * 365))\
.add_extension(basic_contraints, False)\
.add_extension(san, False)\
.add_extension(key_usage, True)\
.add_extension(extended_key_usage, False)\
.sign(key, hashes.SHA256())
** .add_extension(subject_key, False)
.add_extension(authority_key, False)**
# Write cert to file
server_cert = self.log_directory + '/server.cert.pem'
with open(server_cert, 'wb') as f:
f.write(cert.public_bytes(encoding=serialization.Encoding.PEM))
When I run this, I get an error --
> File
> "/teams/subhish/pyuniti/projects/sqa/scripts/BSL/TC_31v03_03_01_02_01_ASCG_configuration_and_bring_up.py",
> line 219, in generate_selfsigned_cert
> x509.CertificateBuilder() File "/venvs/subhish/lib/python3.8/site-packages/cryptography/x509/base.py",
> line 723, in sign
> return backend.create_x509_certificate(self, private_key, algorithm) File
> "/venvs/subhish/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py",
> line 1035, in create_x509_certificate
> self._create_x509_extensions( File "/venvs/subhish/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py",
> line 1141, in _create_x509_extensions
> x509_extension = self._create_x509_extension(handlers, extension) File
> "/venvs/subhish/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/backend.py",
> line 1182, in _create_x509_extension
> ext_struct = encode(self, extension.value) File "/venvs/subhish/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py",
> line 393, in _encode_subject_key_identifier
> return _encode_asn1_str_gc(backend, ski.digest) File "/venvs/subhish/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py",
> line 74, in _encode_asn1_str_gc
> s = _encode_asn1_str(backend, data) File "/venvs/subhish/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py",
> line 54, in _encode_asn1_str
> res = backend._lib.ASN1_OCTET_STRING_set(s, data, len(data)) TypeError: object of type '_RSAPublicKey' has no len()
The documentation says this --
digest
Type: bytes
The binary value of the identifier. An alias of key_identifier.
But I can't figure out how to generate the key_identifier with python/cryptography. It is my understanding this value needs to be generated from the public_key as per RFC5280 (4.2.1.2, 4.2.1.1) from the private_key.
In the end I want to generate a certificate with the following X509 extensions --
X509v3 extensions:
X509v3 Subject Key Identifier:
CA:38:62:01:AA:0D:AA:EC:18:55:E4:A6:93:36:32:F5:97:F2:5F:88
X509v3 Authority Key Identifier:
keyid:CA:38:62:01:AA:0D:AA:EC:18:55:E4:A6:93:36:32:F5:97:F2:5F:88
X509v3 Basic Constraints:
CA:TRUE, pathlen:0
X509v3 Key Usage: critical
Digital Signature, Key Encipherment, Certificate Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:abcd.xyz.net
Any help would be greatly appreciated. Thanks - Subhish
SubjectKeyIdentifier and AuthorityKeyIdentifier do not take the public key in their constructors. If you want to construct a typical identifier via the public key then you should use AuthorityKeyIdentifier.from_issuer_public_key and SubjectKeyIdentifier.from_public_key.
Yep, that worked.
Modified the lines like this --
subject_key = x509.SubjectKeyIdentifier.from_public_key(key.public_key())
authority_key = x509.AuthorityKeyIdentifier.from_issuer_public_key(key.public_key())
Thanks Paul!
Could you help me with m2crypto?
The code below is to return the 'HTTP / 1.1 403 Forbidden' server.
The certificate and the private key are not loaded in the code:
from M2Crypto import Rand, SSL, httpslib, threading , BIO , X509 , RSA
ctx = SSL.Context('sslv23')
store = ctx.get_cert_store()
bio = BIO.MemoryBuffer()
bio.write( str( open( 'certi.pem', 'r' ).read() ) )
store.add_x509( X509.load_cert_bio(bio) )
# or
# store.add_x509( X509.load_cert_string( str(open( 'certi.pem', 'r' ).read()) ) )
ctx.set_verify( SSL.verify_none, depth=1 )
ctx.set_info_callback()
h = httpslib.HTTPSConnection( ‘Server’, 443, ssl_context=ctx )
h.set_debuglevel(1)
h.request( 'mysoap' )
and when I do so, it works:
from M2Crypto import Rand, SSL, httpslib, threading , BIO , X509 , RSA
ctx = SSL.Context('sslv23')
ctx.load_cert_chain( str( 'certi.pem' ) )
ctx.set_verify( SSL.verify_none, depth=1 )
ctx.set_info_callback()
h = httpslib.HTTPSConnection( ‘Server’, 443, ssl_context=ctx )
h.set_debuglevel(1)
h.request( 'mysoap' )
Thank's
I am trying to create a new VM using Pyvmomi. I am successful creating the VM with RAM and CPU, but I cannot find docs on how to create this VM with a disk attached.
I am looking to create a VM with a 20GB thin provisioned HDD, but I cannot find documentation on how to do this.
This is what I am using:
import atexit
import hashlib
import json
import random
import time
import requests
from pyVim import connect
from pyVmomi import vim
from tools import tasks
vc_host = 'vc.example.com'
vc_user = 'john#example.com'
vc_ds = 'datastore1'
vc_password = 'secret'
def create_vm(name, service_instance, vm_folder, resource_pool,datastore):
vm_name = 'VM-' + name
datastore_path = '[' + datastore + '] ' + vm_name
# bare minimum VM shell, no disks. Feel free to edit
vmx_file = vim.vm.FileInfo(logDirectory=None,
snapshotDirectory=None,
suspendDirectory=None,
vmPathName=datastore_path)
config = vim.vm.ConfigSpec(
name=vm_name,
memoryMB=128,
numCPUs=1,
files=vmx_file,
guestId='dosGuest',
version='vmx-07'
)
print "Creating VM {}...".format(vm_name)
task = vm_folder.CreateVM_Task(config=config, pool=resource_pool)
tasks.wait_for_tasks(service_instance, [task])
def main():
name = 'testvm'
service_instance = connect.SmartConnect(host=vc_host,
user=vc_user,
pwd=vc_password,
)
if not service_instance:
print("Could not connect to the specified host using specified "
"username and password")
return -1
atexit.register(connect.Disconnect, service_instance)
content = service_instance.RetrieveContent()
datacenter = content.rootFolder.childEntity[0]
vmfolder = datacenter.vmFolder
hosts = datacenter.hostFolder.childEntity
resource_pool = hosts[0].resourcePool
create_vm(name, service_instance, vmfolder, resource_pool, vc_ds)
return 0
# Start program
if __name__ == "__main__":
main()
First create a VM:
datastore_path = '[datastore1] vm1'
vmx_file = vim.vm.FileInfo(logDirectory=None,
snapshotDirectory=None,
suspendDirectory=None,
vmPathName=datastore_path)
config = vim.vm.ConfigSpec(
name=vm_name,
memoryMB=2048,
numCPUs=cpu,
files=vmx_file,
guestId=None,
version='vmx-07'
)
hostobj = <get the esx host object>
vm_folder = hostobj.vm[0].parent
resource_pool = hostobj.vm[0].resourcePool
task = vm_folder.CreateVM_Task(config=config, pool=resource_pool)
Then reconfigure the VM by adding required devices:
spec = vim.vm.ConfigSpec()
scsi_ctr = vim.vm.device.VirtualDeviceSpec()
scsi_ctr.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
scsi_ctr.device = vim.vm.device.VirtualLsiLogicController()
scsi_ctr.device.deviceInfo = vim.Description()
scsi_ctr.device.slotInfo = vim.vm.device.VirtualDevice.PciBusSlotInfo()
scsi_ctr.device.slotInfo.pciSlotNumber = 16
scsi_ctr.device.controllerKey = 100
scsi_ctr.device.unitNumber = 3
scsi_ctr.device.busNumber = 0
scsi_ctr.device.hotAddRemove = True
scsi_ctr.device.sharedBus = 'noSharing'
scsi_ctr.device.scsiCtlrUnitNumber = 7
unit_number = 0
controller = scsi_ctr.device
disk_spec = vim.vm.device.VirtualDeviceSpec()
disk_spec.fileOperation = "create"
disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
disk_spec.device = vim.vm.device.VirtualDisk()
disk_spec.device.backing = \
vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
disk_spec.device.backing.diskMode = 'persistent'
disk_spec.device.backing.fileName = '[%s] %s/%s.vmdk' % \
( ds_name, client, vmdk_name )
disk_spec.device.unitNumber = unit_number
disk_spec.device.capacityInKB = <size in kb>
disk_spec.device.controllerKey = controller.key
dev_changes = []
dev_changes.append( scsi_ctr )
dev_changes.append( disk_spec )
spec.deviceChange = dev_changes
vmobj.ReconfigVM_Task( spec=spec )
I can't see what you have initialized in devices
So you can try something like this
vdisk_pec = vim.vm.device.VirtualDeviceSpec()
vdisk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
vdisk_spec.operation.backing = vim.vm.device.VirtualDisk.RawDiskVer2BackingInfo()
vdisk_spec.operation.backing.changeId = change_id
vdisk_spec.operation.backing.descriptorFileName = descriptor_file_name
then append vdisk_spec to your devices