private ServiceResult OnFinishRequest( ISystemContext context, MethodState method, NodeId objectId, NodeId applicationId, NodeId requestId, ref byte[] certificate, ref byte[] privateKey, ref byte[][] issuerCertificates) { issuerCertificates = null; HasApplicationAdminAccess(context); var done = m_database.CompleteCertificateRequest(applicationId, requestId, out certificate, out privateKey); if (!done) { return(new ServiceResult(StatusCodes.BadNothingToDo, "The request has not been approved by the administrator.")); } CertificateGroup certificateGroup = GetGroupForCertificate(certificate); issuerCertificates = new byte[1][]; issuerCertificates[0] = certificateGroup.Certificate.RawData; return(ServiceResult.Good); }
private NodeId GetTrustListId(NodeId certificateGroupId) { if (NodeId.IsNull(certificateGroupId)) { certificateGroupId = DefaultApplicationGroupId; } CertificateGroup certificateGroup = null; if (m_certificateGroups.TryGetValue(certificateGroupId, out certificateGroup)) { return(certificateGroup.DefaultTrustList?.NodeId); } return(null); }
private string GetSubjectName(ApplicationRecordDataType application, CertificateGroup certificateGroup, string subjectName) { bool contextFound = false; var fields = Utils.ParseDistinguishedName(subjectName); StringBuilder builder = new StringBuilder(); foreach (var field in fields) { if (builder.Length > 0) { builder.Append(","); } if (field.StartsWith("CN=", StringComparison.Ordinal)) { if (certificateGroup.Id == DefaultHttpsGroupId) { var error = CheckHttpsDomain(application, field.Substring(3)); if (StatusCode.IsBad(error.StatusCode)) { builder.Append("CN="); builder.Append(GetDefaultHttpsDomain(application)); continue; } } } contextFound |= (field.StartsWith("DC=", StringComparison.Ordinal) || field.StartsWith("O=", StringComparison.Ordinal)); builder.Append(field); } if (!contextFound) { if (!String.IsNullOrEmpty(m_configuration.DefaultSubjectNameContext)) { builder.Append(m_configuration.DefaultSubjectNameContext); } } return(builder.ToString()); }
protected void SetCertificateGroupNodes(CertificateGroup certificateGroup) { certificateGroup.CertificateType = Opc.Ua.ObjectTypeIds.ApplicationCertificateType; certificateGroup.DefaultTrustList = null; switch (certificateGroup.Configuration.Id) { case "Https": certificateGroup.Id = DefaultHttpsGroupId; certificateGroup.CertificateType = Opc.Ua.ObjectTypeIds.HttpsCertificateType; certificateGroup.DefaultTrustList = (TrustListState)FindPredefinedNode(ExpandedNodeId.ToNodeId(Opc.Ua.Gds.ObjectIds.Directory_CertificateGroups_DefaultHttpsGroup_TrustList, Server.NamespaceUris), typeof(TrustListState)); break; case "UserToken": certificateGroup.Id = DefaultUserTokenGroupId; certificateGroup.CertificateType = null; certificateGroup.DefaultTrustList = (TrustListState)FindPredefinedNode(ExpandedNodeId.ToNodeId(Opc.Ua.Gds.ObjectIds.Directory_CertificateGroups_DefaultUserTokenGroup_TrustList, Server.NamespaceUris), typeof(TrustListState)); break; case "Default": certificateGroup.Id = DefaultApplicationGroupId; if (certificateGroup.Configuration.DefaultCertificateHashSize < 256) { certificateGroup.CertificateType = Opc.Ua.ObjectTypeIds.RsaMinApplicationCertificateType; } else if (certificateGroup.Configuration.DefaultCertificateHashSize == 256) { certificateGroup.CertificateType = Opc.Ua.ObjectTypeIds.RsaSha256ApplicationCertificateType; } certificateGroup.DefaultTrustList = (TrustListState)FindPredefinedNode(ExpandedNodeId.ToNodeId(Opc.Ua.Gds.ObjectIds.Directory_CertificateGroups_DefaultApplicationGroup_TrustList, Server.NamespaceUris), typeof(TrustListState)); break; default: throw new NotImplementedException("Custom certificate groups are not implemented. Use Default, Https or UserToken"); } if (certificateGroup.DefaultTrustList != null) { certificateGroup.DefaultTrustList.Handle = new TrustList( certificateGroup.DefaultTrustList, certificateGroup.Configuration.TrustedListPath, certificateGroup.Configuration.IssuerListPath, new TrustList.SecureAccess(HasApplicationUserAccess), new TrustList.SecureAccess(HasApplicationAdminAccess)); } }
protected async Task <CertificateGroup> InitializeCertificateGroup(CertificateGroupConfiguration certificateGroupConfiguration) { if (String.IsNullOrEmpty(certificateGroupConfiguration.SubjectName)) { throw new ArgumentNullException("SubjectName not specified"); } if (String.IsNullOrEmpty(certificateGroupConfiguration.BaseStorePath)) { throw new ArgumentNullException("BaseStorePath not specified"); } CertificateGroup certificateGroup = m_certificateGroupProvider.Create( m_configuration.AuthoritiesStorePath, certificateGroupConfiguration); SetCertificateGroupNodes(certificateGroup); await certificateGroup.Init(); return(certificateGroup); }
private async Task RevokeCertificateAsync(byte[] certificate) { if (certificate != null && certificate.Length > 0) { CertificateGroup certificateGroup = GetGroupForCertificate(certificate); if (certificateGroup != null) { try { var x509 = new X509Certificate2(certificate); await certificateGroup.RevokeCertificateAsync(x509); } catch (Exception e) { Utils.Trace(e, "Unexpected error revoking certificate. {0} for Authority={1}", new X509Certificate2(certificate).Subject, certificateGroup.Id); } } } }
private Boolean?GetCertificateStatus( NodeId certificateGroupId, NodeId certificateTypeId) { CertificateGroup certificateGroup = null; if (m_certificateGroups.TryGetValue(certificateGroupId, out certificateGroup)) { if (!NodeId.IsNull(certificateTypeId)) { if (!Utils.IsEqual(certificateGroup.CertificateType, certificateTypeId)) { return(null); } } return(certificateGroup.UpdateRequired); } return(null); }
/// <summary> /// Does any initialization required before the address space can be used. /// </summary> /// <remarks> /// The externalReferences is an out parameter that allows the node manager to link to nodes /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and /// should have a reference to the root folder node(s) exposed by this node manager. /// </remarks> public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences) { lock (Lock) { base.CreateAddressSpace(externalReferences); m_database.NamespaceIndex = NamespaceIndexes[0]; foreach (var certificateGroupConfiguration in m_configuration.CertificateGroups) { try { CertificateGroup certificateGroup = InitializeCertificateGroup(certificateGroupConfiguration).Result; m_certificateGroups[certificateGroup.Id] = certificateGroup; } catch (Exception e) { Utils.Trace(e, "Unexpected error initializing certificateGroup: " + certificateGroupConfiguration.Id + "\r\n" + e.StackTrace); // make sure gds server doesn't start without cert groups! throw e; } } } }
private ServiceResult OnStartSigningRequest( ISystemContext context, MethodState method, NodeId objectId, NodeId applicationId, NodeId certificateGroupId, NodeId certificateTypeId, byte[] certificateRequest, ref NodeId requestId) { HasApplicationAdminAccess(context); var application = m_database.GetApplication(applicationId); if (application == null) { return(new ServiceResult(StatusCodes.BadNotFound, "The ApplicationId does not refer to a valid application.")); } if (NodeId.IsNull(certificateGroupId)) { certificateGroupId = ExpandedNodeId.ToNodeId(Opc.Ua.Gds.ObjectIds.Directory_CertificateGroups_DefaultApplicationGroup, Server.NamespaceUris); } CertificateGroup certificateGroup = null; if (!m_certificateGroups.TryGetValue(certificateGroupId, out certificateGroup)) { return(new ServiceResult(StatusCodes.BadInvalidArgument, "The CertificateGroupId does not refer to a supported certificateGroup.")); } if (!NodeId.IsNull(certificateTypeId)) { if (!Server.TypeTree.IsTypeOf(certificateGroup.CertificateType, certificateTypeId)) { return(new ServiceResult(StatusCodes.BadInvalidArgument, "The CertificateTypeId is not supported by the certificateGroup.")); } } X509Certificate2 certificate = null; try { string[] domainNames = GetDefaultDomainNames(application); certificate = certificateGroup.SigningRequestAsync( application, domainNames, certificateRequest ).Result; } catch (Exception e) { StringBuilder error = new StringBuilder(); error.Append("Error Generating Certificate=" + e.Message); error.Append("\r\nApplicationId=" + applicationId.ToString()); error.Append("\r\nApplicationUri=" + application.ApplicationUri); error.Append("\r\nApplicationName=" + application.ApplicationNames[0].Text); return(new ServiceResult(StatusCodes.BadConfigurationError, error.ToString())); } requestId = m_database.CreateCertificateRequest( applicationId, certificate.RawData, null, certificateGroup.Id.Identifier as string); // store new app certificate using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_configuration.ApplicationCertificatesStorePath)) { store.Add(new X509Certificate2(certificate.RawData)).Wait(); } if (m_autoApprove) { m_database.ApproveCertificateRequest(requestId, false); } return(ServiceResult.Good); }
private ServiceResult OnStartNewKeyPairRequest( ISystemContext context, MethodState method, NodeId objectId, NodeId applicationId, NodeId certificateGroupId, NodeId certificateTypeId, string subjectName, string[] domainNames, string privateKeyFormat, string privateKeyPassword, ref NodeId requestId) { HasApplicationAdminAccess(context); var application = m_database.GetApplication(applicationId); if (application == null) { return(new ServiceResult(StatusCodes.BadNotFound, "The ApplicationId does not refer to a valid application.")); } if (NodeId.IsNull(certificateGroupId)) { certificateGroupId = ExpandedNodeId.ToNodeId(Opc.Ua.Gds.ObjectIds.Directory_CertificateGroups_DefaultApplicationGroup, Server.NamespaceUris); } CertificateGroup certificateGroup = null; if (!m_certificateGroups.TryGetValue(certificateGroupId, out certificateGroup)) { return(new ServiceResult(StatusCodes.BadInvalidArgument, "The certificateGroup is not supported.")); } if (!NodeId.IsNull(certificateTypeId)) { if (!Server.TypeTree.IsTypeOf(certificateGroup.CertificateType, certificateTypeId)) { return(new ServiceResult(StatusCodes.BadInvalidArgument, "The CertificateType is not supported by the certificateGroup.")); } } if (!String.IsNullOrEmpty(subjectName)) { subjectName = GetSubjectName(application, certificateGroup, subjectName); } else { StringBuilder buffer = new StringBuilder(); buffer.Append("CN="); if ((NodeId.IsNull(certificateGroup.Id) || (certificateGroup.Id == DefaultApplicationGroupId)) && (application.ApplicationNames.Count > 0)) { buffer.Append(application.ApplicationNames[0]); } else if (certificateGroup.Id == DefaultHttpsGroupId) { buffer.Append(GetDefaultHttpsDomain(application)); } else if (certificateGroup.Id == DefaultUserTokenGroupId) { buffer.Append(GetDefaultUserToken()); } if (!String.IsNullOrEmpty(m_configuration.DefaultSubjectNameContext)) { buffer.Append(m_configuration.DefaultSubjectNameContext); } subjectName = buffer.ToString(); } if (domainNames != null && domainNames.Length > 0) { foreach (var domainName in domainNames) { if (Uri.CheckHostName(domainName) == UriHostNameType.Unknown) { return(new ServiceResult(StatusCodes.BadInvalidArgument, "The domainName ({0}) is not a valid DNS Name or IPAddress.", domainName)); } } } else { domainNames = GetDefaultDomainNames(application); } X509Certificate2 newCertificate = null; try { newCertificate = certificateGroup.NewKeyPairRequestAsync( application, subjectName, domainNames, privateKeyFormat, privateKeyPassword).Result; } catch (Exception e) { StringBuilder error = new StringBuilder(); error.Append("Error Generating New Key Pair Certificate=" + e.Message); error.Append("\r\nApplicationId=" + applicationId.ToString()); error.Append("\r\nApplicationUri=" + application.ApplicationUri); return(new ServiceResult(StatusCodes.BadConfigurationError, error.ToString())); } byte[] privateKey; if (privateKeyFormat == "PFX") { privateKey = newCertificate.Export(X509ContentType.Pfx, privateKeyPassword); } else if (privateKeyFormat == "PEM") { privateKey = CertificateFactory.ExportPrivateKeyAsPEM(newCertificate); } else { return(new ServiceResult(StatusCodes.BadInvalidArgument, "Invalid private key format")); } // store only app certificate using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_configuration.ApplicationCertificatesStorePath)) { store.Add(new X509Certificate2(newCertificate.RawData)).Wait(); } requestId = m_database.CreateCertificateRequest( applicationId, newCertificate.RawData, privateKey, certificateGroup.Id.Identifier as string); if (m_autoApprove) { m_database.ApproveCertificateRequest(requestId, false); } return(ServiceResult.Good); }