Giter Site home page Giter Site logo

acme-ps's People

Contributors

carlogarcia avatar casselc avatar dezdez avatar ebekker avatar glatzert avatar johanneshoppe avatar johnlbevan avatar martingc94 avatar mirecad avatar mk-2001 avatar natelowry avatar peterstaev avatar tallen116 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

acme-ps's Issues

Consider inlining Newtonsoft for JSON Serialization

I serialized the ServiceDirectory manually now, but I don't know, if that's good to Keep here.
I'm considering pulling Newtonsofts.JSON for Deserializing the JSON directly into the types.
Essentially the conversion should work oobe, but it didn't in practice...

Random failures and erroractionpreference causing other scripts to fail

When trying to use the acme-ps module in another script to automate renewals it seems to randomly fail for me when Invoke-SignedWebRequest is called. Simply retrying the command tends to get past the error, however on line 1183 the throw can end the script due to the default erroractionpreferece. Simply adding $errroractionpreference = "continue" to acme-ps.psm1 seems to resolve this ending my script (for whatever reason if I add this to the script calling acme-ps it does not work).

  1. Am I thick and is there a better workaround than this?
  2. what are the possibilities of adding this to the main branch? drawbacks?

Edit: changing the throw to a write-error would probably be better, Q1 answered: yes I am

AcmeException Doesn't Exist

To get proper feedback from LE (eg. "rate limit reached"), I needed to do this:

from:

throw [AcmeException]::new($respone.ErrorMessage, $response)

to:

throw [AcmeHttpException]::new($response.ErrorMessage, $response)

and

from ("$this.Message" is read-only):

class AcmeHttpException : System.Exception {
    AcmeHttpException([string]$_message, [AcmeHttpResponse]$_response) {
        $this.Message = $_message;
        $this.Response = $_response;
    }

    [AcmeHttpResponse]$Response;
}

to:

class AcmeHttpException : System.Exception {
    AcmeHttpException([string]$_message, [AcmeHttpResponse]$_response) {
        throw "$($_message)`n$($_response.Content)"
    }
}

Create sample collection

  • Account creation
  • Account changes / deactivation
  • Place an order with a single or multiple dns names
  • Authorize multiple challenges
  • Issue a certificate with generated keys
  • Issue a certificte with custom keys
  • Issue multiple certificates
  • Automatically upgrade IIS certificates (leverages IIS CCS)
  • Import the Certificate Chain (automatically included since 1.2)
  • Convert .pfx to .pem and .key (include chain)
  • Add sample to show failure reasons.

Update Get-Authorization.ps1 to support POST AS Get Request

As per the new acme draft version the methods should support GET AS POST request instead of GET request. I updated the Get Authorization method below and tested it. Please incorporate it into the client

--- a/ACME-PS/functions/Authorization/Get-Authorization.ps1
+++ b/ACME-PS/functions/Authorization/Get-Authorization.ps1
@@ -30,16 +30,26 @@ function Get-Authorization {
[Parameter(Mandatory = $true, Position = 0, ParameterSetName = "FromUrl")]
[ValidateNotNullOrEmpty()]
[uri]

  •    $Url
    
  •    $Url,
    
  •    [Parameter(Mandatory = $true, Position = 0)]
    
  •    [ValidateNotNull()]
    
  •    [ValidateScript({$_.Validate()})]
    
  •    [AcmeState]
    
  •    $State
    

    )

    process {

  •    $payload = @{};
       switch ($PSCmdlet.ParameterSetName) {
           "FromOrder" {
    
  •            $Order.AuthorizationUrls | ForEach-Object { Get-Authorization -Url $_ }
    
  •            $Order.AuthorizationUrls | ForEach-Object { Get-Authorization -Url $_ $State }
           }
           Default {
    
  •            $response = Invoke-AcmeWebRequest $Url -Method GET;
    
  •            #$response = Invoke-AcmeWebRequest $Url -Method POST;
    
  •            $response = Invoke-SignedWebRequest $Url $State $payload;
    
  •            return [AcmeAuthorization]::new($response);
           }
       }
    

Implement Revoke-Certificate

Certificate revocation is not yet implemented.
The CertKey Interface needs to be extended to have Sign(...) and ExportJwsPublicKey(…)

Order fails to create because its rate limited, should return a better error

Hello,

When an order fails to be created because you have been rate limited by Let'sEncrypt it returns the following error:

Cannot find an overload for "new" and the argument count: "2". You cannot call a method on a null-valued expression.

You cannot call a method on a null-valued expression.
At C:\MDaemon\LetsEncrypt\Modules\ACME-PS\1.1.0\ACME-PS.psm1:847 char:67
+ ... tifiers = $order.Identifiers | Foreach-Object { $_.ToString() } | Sor ...
+                                                     ~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
Cannot find an overload for "new" and the argument count: "2".
At C:\MDaemon\LetsEncrypt\Modules\ACME-PS\1.1.0\ACME-PS.psm1:2514 char:9
+         $order = [AcmeOrder]::new($response, $csrOptions);
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

I think the module should be improved to detect errors from Let's Encrypt so that error information can be returned. When I dug into it $response = Invoke-SignedWebRequest $requestUrl $State $payload; (at line 2512) was returning the following:

RequestUri : https://acme-v02.api.letsencrypt.org/acme/new-order
StatusCode : 429
NextNonce : 0001Mwcfu-A5FTl84_LLWqCDHBpSwJrtuaeeyR9QYS1eJDE
Headers : {Link, Server, Replay-Nonce, Date...}
Content : @{type=urn:ietf:params:acme:error:rateLimited; detail=Error creating new order :: too many certificates already issued for exact set of domains: List of domains here : see https://letsencrypt.org/docs/rate-limits/; status=429}
IsError : True
ErrorMessage : Server returned problem (Status: 429).

Allow automatic CertificateKey handling in Order

So - to allow this the following has to happen:

  • Include CertificateKey in Order, since it currently is not saved alongside those objects
  • Allow Complete-Order to call New-CertificateKey, if neccessary (probably opt-in)
  • Change implementation of State to load certain objects ad-hoc (e.g. next-nonce) instead of one-time
  • Add -StatePath Parameter to all cmdlets supporting -State TypeConverter string -> AcmeState

I don't see any donwsides to this approach currently.
Changing the state-object needs caution, due to probability of breaking changes, but else ...

Originally posted by @glatzert in #46 (comment)

Allow Settings for CSR and CertificateExport

Currently the module picks the CN of the certificate from the DNS name list.
Since Update-Order will normally be called before Complete-Order the list is updated from the ACME service, which orders the identifiers by name. Thus the CN will always be the first identifier in alphabetical order.

This Issue is to discuss:

  • approaches to allow modifying the CSR
  • listing other usages of Certificate(Request)Settings, which could be added to an order object.

#17 seems to be an valid approach, but could be refined to allow covering a broader set of use cases.

The certificate generated is not applicable for Exchange 2013

Hi.
Generated a certificate using this module.
I get a PFX file that I import in Exchange 2013
It is imported with an invalid CSP provider:
"Microsoft Software Key Storage Provider"
And you need the provider to be:
"Microsoft Enhanced Cryptographic Provider v1.0"
or
"Microsoft RSA SChannel Cryptographic Provider"

Found a solution to work around this problem
openssl.exe pkcs12 -in certificate.pfx -out certificate.pem -nodes
openssl.exe pkcs12 -export -in certificate.pem -out new_certificate.pfx

After that, the certificate is imported with the desired provider:
"Microsoft Enhanced Cryptographic Provider v1.0"

Can you fix it?

PEM File in AcmeState

We've completed a full regression test going from "1.1.0" to "1.1.4". Looks good Thomas! We are looking forward to a final test of your soon-to-be released "1.1.5" version of "AcmeHttpException".

While reviewing "AcmeState" we noticed something new, a PEM file that looks like:

.\Orders\Order-sPiHXRi3mrAaVVlnaiBlMN27Pe6qXz-ldnXhh0Ixgao.pem

We would prefer not to discard "AcmeState" after each "ACME-PS" run. We use it to diagnose issues, if any. We cleanup the previous "AcmeState" during the next run. So sensitive data can't linger there.

Since "Export-ACMECertificate" explicitly exports to PFX format, can you cleanup the PEM file in the "Orders" folder after "Export-ACMECertificate" completes?

Allow module to be used with PS-Desktop and .NET 4.7.2

Currently the module is set to support PS Core 6.0+ (since the Certificate functions are .NET Core App 2.1 only).
But it's also okay to run it with .NET 4.7.2 since, the relevant functions have been made available there also.
The psd1 should be changed to allow that.

Test coverage is bad

There are currently no meaningful tests.

The test coverage should be 100% for all public functions.
To accomplish this mocking seems the only practical solution.

It might be possible to run an integration test with LE-Staging, but the Completion of an Challenge might be challenging.

Investigate "stateless" approach

First, I don't mean to pile on because I think the work you've done here is terrific Tom. Thank you for making such a valuable contribution to the developer community. And please let me know if my next comments would be more appropriate elsewhere.

I have seen the same issue reported by Slamich and I independently arrived at the same solution (ie. "openssl.exe"). I am fine with leaving it at that.

"The fact is that there were no such problems with the previous ASMESharp module."

This is my real concern.

I am sure there are many others who migrated to "ACME-PS" from "ASMESharp" (who are also very grateful for your efforts Tom). With that migration in mind I have been wondering about something else.

One nice feature of "ASMESharp" was its "stateless" implementation (ie. it saved 100% of its own state to disk). That approach allowed its various commands to be run independently in multiple (ie. separate) Powershell sessions (one after another) without concern for losing state.

"ACME-PS" does not allow this. While "ACME-PS" saves some of its state to disk, the balance requires the use of temporary in-memory PS variables. That means users must complete the entire process in a single Powershell session.

Can you please explain that design choice Tom? Is there an easy way to arrive at a similar "stateless" approach (ie. similar to how "ASMESharp" manages 100% of its own state itself) ?

Originally posted by @GeorgeSchiro in #45 (comment)

The last few steps... From PFX to Apache...

Hi
I'm able to get a PFX file, but if I tru to access it using OpenSSL i am promptet for a password ?

$order.CertificateUrl gives me an URL and that URL downloads a file with two certificates inside.
Is this two certificates two out of three of those I need ?

SSLCertificateFile "C:/Apache/g12ssl/www_sublim_dk/certificate.crt"
SSLCertificateKeyFile "C:/Apache/g12ssl/www_sublim_dk/private.key"
SSLCACertificateFile "C:/Apache/g12ssl/www_sublim_dk/ca_bundle.crt"

Please be aware that lot's of people just need some certificates. We don't nedd to understand the depth of ACME. So when you write this:

The certificate chain is not part of the issued certifcate. To get a correct certificate chain, you'll need to import the intermediate certificates from your acme service. For Lets Encrypt you can obtain them via https://letsencrypt.org/certificates/.

Then some of us are left behind...
Will it be possible to do some guidence so that we can make PowerShell, AcmeV2 and Apache to live together ?

LetsEncrypt-Staging returned ResourceUrl and AuthorizationUrls do not work properly

When using LetsEncrypt-Staging, the ResourceUrl and AuthorizationUrls are supposed to show the output/errors for a particular challenge. However they do not work properly. Instead of showing proper valid output, they show an error instead.

An example is https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/47902800

{
  "type": "urn:ietf:params:acme:error:malformed",
  "detail": "Method not allowed",
  "status": 405
}

This error 405 might be apparently related to a recent change in LetsEncrypt-Staging where anonymous requests result in this. But I'm not sure as I'm not familiar enough with the protocol.

Note, I'm not sure if it breaks the whole challenge or not. The returned result shows "Status : valid" but my script sometimes throws an exception when I try to Export-ACMECertificate but of course I can't see why.

ACME-PS v1.1.5
Az.Accounts v1.7.3
Az.automation v1.3.6

Full chain certificate

Hi,

Thanks for the work on your module, it works great! I do have one issue, which might already be supported, but I can't seem to find a solution right now.

Currently when completing a request for a new certificate I'm getting the cert fine, but I'm not getting the full chain. From certbot this is the fullchain.pem file. This is sadly required for some Java applications which is running against my application. https://www.ssllabs.com also reports a missing file in the chain. Any suggestion on who I can mitigate it?

Here's my full script to update:

# Create a new state object for the LetsEncrypt Module
$state = New-ACMEState -Path $env:TEMP
$serviceName = 'LetsEncrypt'

# Fetch the service directory and save it in the state
Get-ACMEServiceDirectory $state -ServiceName $serviceName -PassThru

# Get the first anti-replay nonce
New-ACMENonce $state

# Create an account key. The state will make sure it's stored.
New-ACMEAccountKey $state -PassThru

# Register the account key with the acme service. The account key will automatically be read from the state
New-ACMEAccount $state -EmailAddresses $EmailAddress -AcceptTOS

# Load an state object to have service directory and account keys available
$state = Get-ACMEState -Path $env:TEMP

# It might be neccessary to acquire a new nonce, so we'll just do it for the sake of the example.
New-ACMENonce $state -PassThru

# Create the identifier for the DNS name
$identifier = New-ACMEIdentifier $domain

# Create the order object at the ACME service.
$order = New-ACMEOrder $state -Identifiers $identifier

# Fetch the authorizations for that order
$authZ = Get-ACMEAuthorization -State $state -Order $order

# Select a challenge to fullfill
$challenge = Get-ACMEChallenge $state $authZ "http-01"

# Inspect the challenge data
$challenge.Data

# Gets the content of the challenge
$challengeContent = $challenge.Data.Content

# Create the file requested by the challenge
$fileName = $env:TMP + '\' + $challenge.Token
Set-Content -Path $fileName -Value $challengeContent -NoNewline

# Stores the challenge file in a public storage account
$blobName = ".well-known/acme-challenge/" + $challenge.Token
$storageAccount = Get-AzStorageAccount -ResourceGroupName $STResourceGroupName -Name $storageName
$ctx = $storageAccount.Context

# Set the Blob Content type so it shows in a browser
$blobProperties = @{
    "ContentType" = "text/plain; charset=utf-8"
}

Set-AzStorageBlobContent -File $fileName -Container $stContainer -Context $ctx -Blob $blobName -Properties $blobProperties

# Signal the ACME server that the challenge is ready
$challenge | Complete-ACMEChallenge $state

# Wait a little bit and update the order, until we see the states
while ($order.Status -notin ("ready", "invalid"))
{
    Start-Sleep -Seconds 10
    $order | Update-ACMEOrder $state -PassThru
}

# We should have a valid order now and should be able to complete it
# Therefore we need a certificate key
$certKey = New-ACMECertificateKey -Path "$env:TEMP\$domain.key.xml"

# Complete the order - this will issue a certificate singing request
Complete-ACMEOrder $state -Order $order -CertificateKey $certKey

# Now we wait until the ACME service provides the certificate url
while (-not $order.CertificateUrl)
{
    Start-Sleep -Seconds 15
    $order | Update-ACMEOrder $state -PassThru
}

# As soon as the url shows up we can create the PFX
$password = ConvertTo-SecureString -String $CertPW -Force -AsPlainText
Export-ACMECertificate $state -Order $order -CertificateKey $certKey -Path "$env:TEMP\$domain.pfx" -Password $password

Typo in ACME-PS 1.1.4

In line 1389 you call the parameter "Suppresskeyid" however the function parameter is named "Supresskeyid" resulting in an error.

Az module cmdlets fail when ACME-PS module loaded

I have an Azure Automation runbook that uses ACME-PS and Az.Storage modules.
When ACME-PS module (1.1.5) is loaded, cmdlets from Az.Storage (1.12.0) throw exceptions.

Runbook script

$ErrorActionPreference = 'Stop'

"Loaded modules:"
Get-Module

$connectionName = "AzureRunAsConnection"

try
{
    # Get the connection "AzureRunAsConnection "

    $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName

    "Logging in to Azure..."
    $connectionResult =  Connect-AzAccount -Tenant $servicePrincipalConnection.TenantID `
                             -ApplicationId $servicePrincipalConnection.ApplicationID   `
                             -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint `
                             -ServicePrincipal
    "Logged in."

}
catch {
    if (!$servicePrincipalConnection)
    {
        $ErrorMessage = "Connection $connectionName not found."
        throw $ErrorMessage
    } else{
        Write-Error -Message $_.Exception
        throw $_.Exception
    }
}


$stateDir = "$($PWD.Path)\acmestate-LetsEncrypt-Staging"

# Ensure state directory exists
if(!(Test-Path $stateDir -t Container)){
    New-Item -ItemType Directory -Force -Path $stateDir | Out-Null
}

if(Get-Module 'ACME-PS'){"Module ACME-PS is loaded"}else{"Module ACME-PS is not loaded"}

"New-ACMEState:"
# *** Comment/Uncomment the following line to trigger crashes
# *** Note that once uncommented, the crashes will recur even AFTER the line is commented out again
$state = New-ACMEState -Path $stateDir

if(Get-Module 'ACME-PS'){"Module ACME-PS is loaded"}else{"Module ACME-PS is not loaded"}

if(Get-Module 'ACME-PS'){
    # This line does not appear to have any effect
    "Unloading Removing module ACME-PS"
    Remove-Module 'ACME-PS' -Force -Verbose
}
if(Get-Module 'ACME-PS'){"Module ACME-PS is loaded"}else{"Module ACME-PS is not loaded"}

try{
    "Get-AzContext: "
    $AzStorageProfile = Get-AzContext -ListAvailable | ? { $_.Subscription.Name -eq 'Pay-As-You-Go' }
    $AzStorageProfile

    "Get-AzStorageAccount: "
    $AzStorageAcc = Get-AzStorageAccount -Name '__REDACTED_STORAGE_ACCOUNT_NAME__' -ResourceGroupName '__REDACTED_STORAGE_ACCOUNT_RG_NAME__' -DefaultProfile $AzStorageProfile
    $AzStorageAcc
}
catch [System.Management.Automation.CommandNotFoundException]{
    "Caught exception!"
    $_ | Select-Object -Property *
}

Exception details

System.Management.Automation.CommandNotFoundException: The 'Get-AzStorageAccount' command was found in the module 'Az.Storage', but the module could not be loaded. For more information, run 'Import-Module Az.Storage'. ---> System.Management.Automation.CmdletInvocationException: The following error occurred while loading the extended type data file: 
Microsoft.PowerShell, C:\Modules\User\ACME-PS\Types.ps1xml(8) : Error in type "AcmeState": The "Type" node must have "Members", "TypeConverters", or "TypeAdapters".
Microsoft.PowerShell, C:\Modules\User\ACME-PS\Types.ps1xml(11) : Error: Unable to find type [AcmeObjectConverter].
Microsoft.PowerShell, C:\Modules\User\ACME-PS\Types.ps1xml(2) : Error in type "AcmeIdentifier": The "Type" node must have "Members", "TypeConverters", or "TypeAdapters".
Microsoft.PowerShell, C:\Modules\User\ACME-PS\Types.ps1xml(5) : Error: Unable to find type [AcmeObjectConverter].
 ---> System.Management.Automation.RuntimeException: The following error occurred while loading the extended type data file: 
Microsoft.PowerShell, C:\Modules\User\ACME-PS\Types.ps1xml(8) : Error in type "AcmeState": The "Type" node must have "Members", "TypeConverters", or "TypeAdapters".
Microsoft.PowerShell, C:\Modules\User\ACME-PS\Types.ps1xml(11) : Error: Unable to find type [AcmeObjectConverter].
Microsoft.PowerShell, C:\Modules\User\ACME-PS\Types.ps1xml(2) : Error in type "AcmeIdentifier": The "Type" node must have "Members", "TypeConverters", or "TypeAdapters".
Microsoft.PowerShell, C:\Modules\User\ACME-PS\Types.ps1xml(5) : Error: Unable to find type [AcmeObjectConverter].

   at System.Management.Automation.Runspaces.FormatAndTypeDataHelper.ThrowExceptionOnError(String errorId, Collection`1 independentErrors, Collection`1 PSSnapinFilesCollection, RunspaceConfigurationCategory category)
   at System.Management.Automation.Runspaces.RunspaceConfigurationEntryCollection`1.Update(Boolean force)
   at Microsoft.PowerShell.Commands.ModuleCmdletBase.LoadModuleManifest(String moduleManifestPath, ExternalScriptInfo manifestScriptInfo, Hashtable data, Hashtable localizedData, ManifestProcessingFlags manifestProcessingFlags, Version minimumVersion, Version maximumVersion, Version requiredVersion, Nullable`1 requiredModuleGuid, ImportModuleOptions& options, Boolean& containedErrors)
   --- End of inner exception stack trace ---
   at System.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input)
   at System.Management.Automation.PowerShell.Worker.ConstructPipelineAndDoWork(Runspace rs, Boolean performSyncInvoke)
   at System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
   at System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
   at System.Management.Automation.PowerShell.Invoke[T]()
   at System.Management.Automation.CommandDiscovery.AutoloadSpecifiedModule(String moduleName, ExecutionContext context, SessionStateEntryVisibility visibility, Exception& exception)
   --- End of inner exception stack trace ---
   at System.Management.Automation.CommandDiscovery.TryModuleAutoDiscovery(String commandName, ExecutionContext context, String originalCommandName, CommandOrigin commandOrigin, SearchResolutionOptions searchResolutionOptions, CommandTypes commandTypes, Exception& lastError)
   at System.Management.Automation.CommandDiscovery.LookupCommandInfo(String commandName, CommandTypes commandTypes, SearchResolutionOptions searchResolutionOptions, CommandOrigin commandOrigin, ExecutionContext context)
   at System.Management.Automation.CommandDiscovery.LookupCommandProcessor(String commandName, CommandOrigin commandOrigin, Nullable`1 useLocalScope)
   at System.Management.Automation.ExecutionContext.CreateCommand(String command, Boolean dotSource)
   at System.Management.Automation.PipelineOps.AddCommand(PipelineProcessor pipe, CommandParameterInternal[] commandElements, CommandBaseAst commandBaseAst, CommandRedirection[] redirections, ExecutionContext context)
   at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
   at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

List of modules installed in automation account

Name Last modified Status Version
ACME-PS 18/02/2020, 11:27 am Available 1.1.5
AuditPolicyDsc 27/02/2020, 8:07 pm Available 1.1.0.0
Az.Accounts 02/03/2020, 9:57 am Available 1.7.2
Az.Automation 02/03/2020, 9:59 am Available 1.3.6
Az.Dns 19/02/2020, 3:51 pm Available 1.1.2
Az.Resources 02/03/2020, 9:59 am Available 1.11.0
Az.Sql 02/03/2020, 9:59 am Available 2.3.0
Az.Storage 18/02/2020, 10:52 am Available 1.12.0
Azure 25/02/2020, 10:44 am Available 5.3.0
Azure.Storage 25/02/2020, 10:41 am Available 4.6.1
AzureRM.Automation 25/02/2020, 10:41 am Available 6.1.1
AzureRM.Compute 25/02/2020, 10:41 am Available 5.9.1
AzureRM.Profile 25/02/2020, 10:39 am Available 5.8.3
AzureRM.Resources 25/02/2020, 10:41 am Available 6.7.3
AzureRM.Sql 25/02/2020, 10:41 am Available 4.12.1
AzureRM.Storage 25/02/2020, 10:43 am Available 5.2.0
ComputerManagementDsc 27/02/2020, 8:06 pm Available 5.0.0.0
GPRegistryPolicyParser 27/02/2020, 8:07 pm Available 0.2
REDACTED_PRIVATE_MODULE 02/03/2020, 11:25 am Available 1.0.0.2
Microsoft.PowerShell.Core 27/02/2020, 7:55 pm Available 0.0
Microsoft.PowerShell.Diagnostics 27/02/2020, 7:55 pm Available Microsoft.PowerShell.Management
PSDscResources 27/02/2020, 8:08 pm Available 2.9.0.0
SecurityPolicyDsc 27/02/2020, 8:07 pm Available 2.1.0.0
StateConfigCompositeResources 27/02/2020, 8:09 pm Available 1.0
xDSCDomainjoin 27/02/2020, 8:06 pm Available 1.1
xPowerShellExecutionPolicy 27/02/2020, 8:05 pm Available 1.1.0.0
xRemoteDesktopAdmin 27/02/2020, 8:06 pm Available 1.1.0.0

Howto: key as pem

Hi,

is it possible to get the private key as pem? I know, i can export the certificate as .pfx and afterwards convert it via openssl. But i think the ability to export the key pem would be helpful.

BR
JoePhanDro

Exception setting "expires": "Cannot convert null to type "System.DateTimeOffset"."

We started full regression testing of "1.1.5" this morning and noticed an error not seen before. So we went back to "1.1.4" (which tested fine several days ago) to see if we get the same error. We did:

$challenge | Complete-ACMEChallenge "C:\Users\admin\Desktop\tmp\AcmeState"

Exception calling "GetResult" with "0" argument(s): "An error occurred while sending the request."
At C:\Users\admin\Desktop\tmp\ACME-PS\1.1.4\ACME-PS.psm1:1344 char:5
+     $httpResponse = $httpClient.SendAsync($httpRequest).GetAwaiter(). ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : HttpRequestException

Exception setting "expires": "Cannot convert null to type "System.DateTimeOffset"."
At C:\Users\admin\Desktop\tmp\ACME-PS\1.1.4\ACME-PS.psm1:750 char:9
+         $this.expires = $httpResponse.Content.expires;
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting

At first we thought it might be a problem with LE. Then we bounced the server and the problem went away.

Should this error possibly be handled differently? Perhaps at least a null check on the "expires" value?

"Order-xxxyyyzzz.key.xml already exists. This method will not override existing files" on renew

You mentioned in Issue #36 that it doesn't differentiate between renewals and new requests. However following the samples through and then re-running it to force a renewal results in

`Order-yyyyyyzzz.key.xml already exists. This method
will not override existing files
At C:\Program Files\WindowsPowerShell\Modules\ACME-PS\1.1.5\ACME-PS.psm1:2207 char:13

  •         throw "$Path already exists. This method will not overrid ...
    
  •         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : OperationStopped: (D:\iisroot_glo... existing files:String) [], RuntimeException
    • FullyQualifiedErrorId : c:\iisroot\Order-xxxyyyzzz.xml
      already exists. This method will not override existing files`

Which is correct, as the Service\Orders folder contains the
Order-yyyyyyzzz.key.xml
Order-yyyyyyzzz.xml
Order-yyyyyyzzz.pem

and OrderList.txt contains the entry as well.

Are you proposing that these should be cleaned up manually, or is there a method currently not show in the samples to perform a clean-up to permit a renewal run to occur?

Thanks,

How to use ACME-PS with SANs

Hi,
please help.
I have tried to supply an array [AcmeIdentifier[]] for the New-ACMEOrder
that sows an error in the next function: Get-ACMEAuthorization

# Create the identifier for the DNS name $ACMEIdentifierCN = New-ACMEIdentifier $LECERT_ServerCN;
# Build Identifier-Array
[AcmeIdentifier[]] $ACMEIdentifiers = $NULL;
$ACMEIdentifiers +=$ACMEIdentifierCN;

#Add SANs
foreach ($SAN in $LECERT_SANs)
{
      $ACMEIdentifiers += New-ACMEIdentifier $SAN
}


# Create the order object at the ACME service.
$ACMEOrder = New-ACMEOrder $ACMEState  -Identifiers $ACMEIdentifiers;

# Fetch the authorizations for that order
$ACMEauthZ = Get-ACMEAuthorization  -Order $ACMEOrder;

Error:
-> The type System.Object[] cannot converted into type AcmeAuthorization
original (in german)
Get-ACMEChallenge : Die Argumenttransformation für den Parameter "Authorization" kann nicht verarbeitet werden. Der Wert "System.Object[]" vom Typ "System.Object[]" kann nicht in den Typ "AcmeAuthorization" konvertiert werden.

is there some problem if the identifier is not even a single value?
how does it work to get a certificate with more than one name (SANs)?

Typo in README.md

Thomas,

You still have the "Authroization" typo in your readme.

That said, this "issue" is just an excuse to let you know we've been testing V1.1.5 for the past 2 months with no issues and how impressed we are!

You've done excellent work and you should be very proud of it Thomas.

Thank you!

'Geo

Ps. You should also know that we were nonplussed when we learned your tool (a replacement for "ACMESharp" - after ACME v1 was deprecated) contains no DLLs! We were amazed to see your code doing everything the former could - with PS only! It's an unbelievably clean solution which makes our "GetCert2" that much cleaner than its predecessor as a result. Then, on top of all that, your non-hesitant willingness to add session independence (between ACME-PS calls) put our admiration over the top. Kudos my friend. If we can make a donation. please let me know how.

A Little More Feedback Would Be Nice

These commands offer feedback upon successful completion:

Complete-ACMEChallenge
Export-ACMECertificate (in the form of a PFX file)
Get-ACMEServiceDirectory
New-ACMEAccountKey
New-ACMEOrder
New-ACMEState
Update-ACMEOrder

These don't:

Complete-ACMEOrder
Get-ACMEAuthorization
New-ACMEAccount
New-ACMENonce

It would be nice if at least "Complete-ACMEOrder" offered some feedback.

Thank you again for all of your great effort Thomas. The tool is excellent.

Complete-ACMEOrder with multiple domains doesn't work

When I try to run Complete-ACMEOrder with an order with multiple identifiers, I get this error:

Server returned Problem: {
  "type": "urn:ietf:params:acme:error:malformed",
  "detail": "Error finalizing order :: policy forbids issuing for: \"*.standardaction.net standardaction.net\"",
  "status": 400
}
At C:\Program Files\WindowsPowerShell\Modules\ACME-PS\1.0.2\ACME-PS.psm1:1081 char:9                            
+         throw "Server returned Problem: $response"                                                            
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                            
    + CategoryInfo          : OperationStopped: (Server returned..."status": 400                                
}:String) [], RuntimeException                                                                                  
    + FullyQualifiedErrorId : Server returned Problem: {                                                        
  "type": "urn:ietf:params:acme:error:malformed",                                                               
  "detail": "Error finalizing order :: policy forbids issuing for: \"*.standardaction.net standardaction.net\"",
  "status": 400                                                                                                 
}                                 

Leaking AcmeState

First, the new "stateless" features (which are really "stateful" - ie. session independent, see #46) are working great! Thank you Thomas.

I've completed most of my testing and noticed only one issue: new state is not limited to the "{path to AcmeState}" folder (where "{path to AcmeState}" is the path given to "New-ACMEState").

New state items are appearing in the parent folder of "{path to AcmeState}":

"{path to AcmeState}Orders\"
"{path to AcmeState}Account.xml"
"{path to AcmeState}AccountKey.xml"

Can you move the new state to the "{path to AcmeState}" folder?

IIS and Files without extension, probably a easy solution

I was looking for a suitable solution to automate the IIS-Configuration to support files (mime-types) without extension. I have found a way to do this with powershell and don't have to config that by GUI but: (for me) the solution in the comments dit not work.
I think that was because there is also a handler configuration change neccessary.

After a lot of reading i found a probably better solution: Place a web.config into the challenge directory.
You can copy it from elsewhere or create ist with Set-Content.
At the end the web-config has do exist next to the challenge file before the Check if the challenge is readable ( Invoke-WebRequest $challenge.Data.AbsoluteUrl)
That works for me (Server2016 / IIS10 )without the need of a GUI

Content of web.config (sorry for the format):
<?xml version = "1.0" encoding="UTF-8"?> <configuration> <system.webServer> <staticContent> <mimeMap fileExtension="." mimeType="text/plain" /> <mimeMap fileExtension=".*" mimeType="text/plain" /> </staticContent> <handlers> <clear /> <add name="StaticFile" path="*" verb="*" type="" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" scriptProcessor="" resourceType="Either" requireAccess="Read" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" /> </handlers> </system.webServer> </configuration>

Complete-ACMEChallenge : unresolved site for given site reference

Environment

OS: Windows 2012 R2
Powershell: 5.1
Webserver: IIS

Description

Trying to automate my IIS server certificate using this ACME client. I followed the docs (including all the validation steps) up to the command Complete-ACMEChallenge:

The Exact Command

Complete-ACMEChallenge -IdentifierRef portal -ChallengeType http-01 -Handler iis -HandlerParameters @{WebSiteRef = 'Portal'}

The Error

Complete-ACMEChallenge : unresolved site for given site reference
At line:1 char:1
+ Complete-ACMEChallenge -IdentifierRef portal -ChallengeType http-01 - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Complete-ACMEChallenge], InvalidOperationException
    + FullyQualifiedErrorId : System.InvalidOperationException,ACMESharp.POSH.CompleteChallenge

Looks like the iis handler can't find my IIS site Portal but if I do Get-Website I get the following:

Name             ID   State      Physical Path                  Bindings
----             --   -----      -------------                  --------
Portal           2    Started    C:\inetpub\wwwroot             https *:443: sslFlags=0

Any idea what am I doing wrong ?

Get-ServiceDirectory

The main readme has Get-ServiceDirectory but I think it should be Get-ACMEServiceDirectory. THe first option failed when I attempted to run the script.

Status: Invalid error

Hello,

First of all I wanted to express my appreciation for this Powershell module that support Acme v,2 protocol. Really great work. It was working perfectly till today..

I managed to issue certificates for may domains, but today when script was running I get the Status: Invalid

I have deleted AcmeState folder and tried to rerun the script, same error. Also Absolute Url is available and can be requested.

Thanks in advance for the help.

logs.txt
AcmeState.zip

Allow defining Proxy in $env:

Moving the ACME-PS commands to another domain with my employee showed, that WPAD will be used.
Unfortunately WPAD is not available everywhere so we need to allow usage of a defined proxy.

Since it's common in *nix, we'll go for $env:HTTP_PROXY probably.

.* use in IISExtensionless

In your IISExtensionless.md sample you have:
<mimeMap fileExtension=".*" mimeType="text/plain" />

It should be:
<mimeMap fileExtension="." mimeType="text/plain" />

.* causes the directory to be unreadable client side

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.