3

I am trying to upload a ssl cert to the f5 REST API and haven't found anyone using powershell to do it. I have setup the invoke-webrequest around this page that is using curl f5-Dev-central

the f5 is: BIG-IP 13.1.1 Build 0.0.4 Final

i am getting the following error

Invoke-webrequest : {"code":400,"message":"Chunk byte count 8802 in Content-Range header different from received buffer length 162","originalRequestBody":

this is part of the script:

....
#read the size of the file with the correct encoding
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
$basicAuthValue = "Basic $encodedCreds"

$file = [IO.File]::ReadAllBytes($pathtofile)
$enc = [System.Text.Encoding]::GetEncoding("iso-8859-1")
$encodedfile = $enc.GetString($file)

#get range of bytes for entire file in start-end/total format
$range = "0-" + ($encodedfile.Length - 1) + "/" + $encodedfile.Length

#create parts for invoke-webrequest call 

#create header json
$headers = @{"Content-Range" = $range; Authorization = $basicAuthValue}

$uri = "https://$bigip/mgmt/shared/file-transfer/bulk/uploads/$nameofcert.crt"

$params = @{'command'="install";'name'="$nameofcert";'from-local-file'=$pathtofile}
$json = $params | ConvertTo-Json

#run the invoke
Invoke-webrequest -Method POST -uri $uri -Headers $Headers -Body $json -ContentType 'application/json'
Don Fouts
  • 137
  • 1
  • 11
  • Do you have a working Curl sample ? At a glance $encodedfile looks a bit odd. Also any idea what are 8802 and 162 lengths? – Mike Twc Dec 21 '18 at 18:52
  • 8802 is the total size of the file aka $encodedfile.length not sure where the 162 came from in that error – Don Fouts Dec 21 '18 at 18:54
  • 1
    it might be size of the body json, can you check? Is that script meant to upload that file to the server? – Mike Twc Dec 21 '18 at 18:57
  • curl in powershell is an alias for invoke-webrequest - so to use CURL i would need to move to the linux subsystem or specifically call a CURL.exe – Don Fouts Dec 21 '18 at 18:59
  • 1
    I mean with actual curl . Your sample and the link to curl solution your provide are quie different. Did you use some other curl example? Anyway if the goal is to upload a file, file bytes should be in the request body – Mike Twc Dec 21 '18 at 19:08
  • @MikeTwc that was it - I moved the 'content-range' = $range; into the body - and i also had to add the content-range of the body json into the header... and that worked if you write up an answer i will mark it as correct – Don Fouts Dec 21 '18 at 21:27
  • I actually was thinking to move bytes to body, so you solved it yourself ). Just post a working script so other pepole can use it – Mike Twc Dec 21 '18 at 21:33

1 Answers1

2

So the title of my question is uploading the crt - i am still having problems making the profile on the f5 but i have worked out the issues with uploading the file.

the other part I struggled with was getting the key and cert in the correct format the f5 wanted so i will go over what i did for that as well

i started with a .pfx file: (note i have openssl installed on my windows 2016 server)

openssl pkcs12 -in d:\pathtocert.pfx -out d:\pathtocrtfile.crt -clcerts
openssl pkcs12 -in d:\pathtocert.pfx -out d:\pathtokey.key -nocerts

to get the crt from PEM into the DER format you need to use x509 - this is required for the f5

openssl x509 -inform pem -in d:\pathtocrtfile.crt -outform der -out d:\pathtocrtfile.crt

ok lets get the files on the f5 (i am going to avoid using ftp or something like that - and just leverage the icontrol rest)

$site = 'donsTest'   # hard coding the name for now / could be passed in as an arg
$year = get-date -UFormat "%Y"
$nameofcert = "$site-cer-$year"
$pair = 'f5user:password'
$pathtofile = 'd:\pathtocrtfile.crt'
$keypath = 'd:\pathtokey.key'
$nameofkey = "$site-key-$year"
$nameofprofile = "$site-ssl-$year"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
$basicAuthValue = "Basic $encodedCreds"
$bigip = 'iporURLTOF5'

####################################
#  get crt file ready for upload
####################################

ok lets put this crt file into the body of our REST call

$file = [IO.File]::ReadAllBytes($pathtofile)
$enc = [System.Text.Encoding]::GetEncoding("iso-8859-1")
$encodedfile = $enc.GetString($file)
$range = "0-" + ($encodedfile.Length - 1) + "/" + $encodedfile.Length  # you need to calculate the size of this file to use in the REST Header

$headers = @{"Content-Range" = $range; Authorization = $basicAuthValue}
$uri = "https://$bigip/mgmt/shared/file-transfer/bulk/uploads/$nameofcert"
$uploadresult = Invoke-webrequest -Method POST -uri $uri -Headers $Headers -Body $encodedfile -ContentType 'application/json' | ConvertFrom-Json
$temppath = $uploadresult.localFilePath

now the file is uploaded to the f5 - we need to install it on the f5 as a cert

### Add new certificate on the f5 from the file you just uploaded
class cert
{
    [string]$command
    [string]$name
    [string]$fromLocalFile
}

$cert = New-Object -TypeName cert
$cert.command = "install"
$cert.name = $nameofcert 
$cert.fromLocalFile = $temppath
$body = $cert | ConvertTo-Json
$headers = @{Authorization = $basicAuthValue}
$url = "https://$bigip/mgmt/tm/sys/crypto/cert"
Invoke-WebRequest $url -method Post -Body $body -Headers $Headers -ContentType "application/json"

the key is the same process except the url for the key install

$url = "https://" + $bigip + "/mgmt/tm/sys/crypto/key"
Invoke-WebRequest $url -method Post -Body $body -Headers $Headers -ContentType "application/json" -Credential $credential | ConvertFrom-Json
Don Fouts
  • 137
  • 1
  • 11