From 14073c14aaa46532b85908be2b503e14e3fe1ad7 Mon Sep 17 00:00:00 2001 From: Carolina Oliveira <61292734+CarolinaOliiveira@users.noreply.github.com> Date: Mon, 9 Sep 2024 12:40:47 +0100 Subject: [PATCH] rename dir to v2_3 Signed-off-by: Carolina Oliveira <61292734+CarolinaOliiveira@users.noreply.github.com> Signed-off-by: Carolina Oliveira <61292734+CarolinaOliiveira@users.noreply.github.com> --- .../{v2_2 => v2_3}/Helpers/Bom/Creators.cs | 200 +++--- .../{v2_2 => v2_3}/Helpers/Bom/Files.cs | 246 ++++---- .../Helpers/Component/AttributionTexts.cs | 118 ++-- .../Helpers/Component/Checksums.cs | 576 +++++++++--------- .../Helpers/Component/ExternalRefs.cs | 306 +++++----- .../Helpers/CycloneDXBomHelpers.cs | 482 +++++++-------- .../{v2_2 => v2_3}/Helpers/General.cs | 280 ++++----- .../Helpers/SpdxDocumentHelpers.cs | 456 +++++++------- .../{v2_2 => v2_3}/SpdxDocumentConverters.cs | 258 ++++---- 9 files changed, 1461 insertions(+), 1461 deletions(-) rename src/CycloneDX.Spdx.Interop/Converters/{v2_2 => v2_3}/Helpers/Bom/Creators.cs (97%) rename src/CycloneDX.Spdx.Interop/Converters/{v2_2 => v2_3}/Helpers/Bom/Files.cs (97%) rename src/CycloneDX.Spdx.Interop/Converters/{v2_2 => v2_3}/Helpers/Component/AttributionTexts.cs (97%) rename src/CycloneDX.Spdx.Interop/Converters/{v2_2 => v2_3}/Helpers/Component/Checksums.cs (97%) rename src/CycloneDX.Spdx.Interop/Converters/{v2_2 => v2_3}/Helpers/Component/ExternalRefs.cs (98%) rename src/CycloneDX.Spdx.Interop/Converters/{v2_2 => v2_3}/Helpers/CycloneDXBomHelpers.cs (98%) rename src/CycloneDX.Spdx.Interop/Converters/{v2_2 => v2_3}/Helpers/General.cs (97%) rename src/CycloneDX.Spdx.Interop/Converters/{v2_2 => v2_3}/Helpers/SpdxDocumentHelpers.cs (98%) rename src/CycloneDX.Spdx.Interop/Converters/{v2_2 => v2_3}/SpdxDocumentConverters.cs (97%) diff --git a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Bom/Creators.cs b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Bom/Creators.cs similarity index 97% rename from src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Bom/Creators.cs rename to src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Bom/Creators.cs index 7882b4bf..7547909c 100644 --- a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Bom/Creators.cs +++ b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Bom/Creators.cs @@ -1,100 +1,100 @@ -// This file is part of CycloneDX Library for .NET -// -// Licensed under the Apache License, Version 2.0 (the “License”); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an “AS IS” BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -// Copyright (c) OWASP Foundation. All Rights Reserved. - -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using CycloneDX.Models; - -namespace CycloneDX.Spdx.Interop.Helpers -{ - public static class Creators - { - public static List GetSpdxCreators(this Bom bom) - { - var creators = new List(); - - if (bom.Metadata?.Tools?.Tools != null) - { - foreach (var tool in bom.Metadata.Tools.Tools) - { - creators.Add($"Tool: {tool.Name}-{tool.Version}"); - } - } - - if (bom.Metadata?.Authors != null) - { - var orgs = bom.Metadata.Properties?.GetSpdxElements(PropertyTaxonomy.CREATION_INFO_LICENSE_CREATORS_ORGANIZATIONS) ?? new List(); - foreach (var author in bom.Metadata.Authors) - { - if (orgs.Contains(author.Name)) - { - creators.Add($"Organization: {author.Name} ({author.Email})"); - } - else - { - creators.Add($"Person: {author.Name} ({author.Email})"); - } - } - } - - return creators.Count == 0 ? null : creators; - } - - public static void AddSpdxCreators(this Bom bom, List creators) - { - if (creators != null) - { - var toolRegex = new Regex(@"Tool: (?.*)-(?.*)"); - var nonToolRegex = new Regex(@"(Person|Organization): (?.*) \((?.*)\)"); - foreach (var creator in creators) - { - var toolMatch = toolRegex.Match(creator); - if (toolMatch.Success) - { - if (bom.Metadata == null) bom.Metadata = new Metadata(); - #pragma warning disable 618 - if (bom.Metadata?.Tools?.Tools == null) - bom.Metadata.Tools = new ToolChoices { Tools = new List() }; - bom.Metadata.Tools.Tools.Add(new Tool { - Name = toolMatch.Groups["name"].ToString(), - Version = toolMatch.Groups["version"].ToString(), - }); - #pragma warning restore 618 - } - else - { - var nonToolMatch = nonToolRegex.Match(creator); - if (nonToolMatch.Success) - { - if (bom.Metadata.Authors == null) bom.Metadata.Authors = new List(); - bom.Metadata.Authors.Add(new OrganizationalContact - { - Name = nonToolMatch.Groups["name"].ToString(), - Email = nonToolMatch.Groups["email"].ToString(), - }); - if (creator.StartsWith("Organization:")) - { - bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.CREATION_INFO_LICENSE_CREATORS_ORGANIZATIONS, nonToolMatch.Groups["name"].ToString()); - } - } - } - } - } - } - } -} +// This file is part of CycloneDX Library for .NET +// +// Licensed under the Apache License, Version 2.0 (the “License”); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an “AS IS” BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) OWASP Foundation. All Rights Reserved. + +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using CycloneDX.Models; + +namespace CycloneDX.Spdx.Interop.Helpers +{ + public static class Creators + { + public static List GetSpdxCreators(this Bom bom) + { + var creators = new List(); + + if (bom.Metadata?.Tools?.Tools != null) + { + foreach (var tool in bom.Metadata.Tools.Tools) + { + creators.Add($"Tool: {tool.Name}-{tool.Version}"); + } + } + + if (bom.Metadata?.Authors != null) + { + var orgs = bom.Metadata.Properties?.GetSpdxElements(PropertyTaxonomy.CREATION_INFO_LICENSE_CREATORS_ORGANIZATIONS) ?? new List(); + foreach (var author in bom.Metadata.Authors) + { + if (orgs.Contains(author.Name)) + { + creators.Add($"Organization: {author.Name} ({author.Email})"); + } + else + { + creators.Add($"Person: {author.Name} ({author.Email})"); + } + } + } + + return creators.Count == 0 ? null : creators; + } + + public static void AddSpdxCreators(this Bom bom, List creators) + { + if (creators != null) + { + var toolRegex = new Regex(@"Tool: (?.*)-(?.*)"); + var nonToolRegex = new Regex(@"(Person|Organization): (?.*) \((?.*)\)"); + foreach (var creator in creators) + { + var toolMatch = toolRegex.Match(creator); + if (toolMatch.Success) + { + if (bom.Metadata == null) bom.Metadata = new Metadata(); + #pragma warning disable 618 + if (bom.Metadata?.Tools?.Tools == null) + bom.Metadata.Tools = new ToolChoices { Tools = new List() }; + bom.Metadata.Tools.Tools.Add(new Tool { + Name = toolMatch.Groups["name"].ToString(), + Version = toolMatch.Groups["version"].ToString(), + }); + #pragma warning restore 618 + } + else + { + var nonToolMatch = nonToolRegex.Match(creator); + if (nonToolMatch.Success) + { + if (bom.Metadata.Authors == null) bom.Metadata.Authors = new List(); + bom.Metadata.Authors.Add(new OrganizationalContact + { + Name = nonToolMatch.Groups["name"].ToString(), + Email = nonToolMatch.Groups["email"].ToString(), + }); + if (creator.StartsWith("Organization:")) + { + bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.CREATION_INFO_LICENSE_CREATORS_ORGANIZATIONS, nonToolMatch.Groups["name"].ToString()); + } + } + } + } + } + } + } +} diff --git a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Bom/Files.cs b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Bom/Files.cs similarity index 97% rename from src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Bom/Files.cs rename to src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Bom/Files.cs index 5f11f3e5..a6bd10ef 100644 --- a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Bom/Files.cs +++ b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Bom/Files.cs @@ -1,123 +1,123 @@ -// This file is part of CycloneDX Library for .NET -// -// Licensed under the Apache License, Version 2.0 (the “License”); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an “AS IS” BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -// Copyright (c) OWASP Foundation. All Rights Reserved. - -using System; -using System.Collections.Generic; -using System.Linq; -using CycloneDX.Models; -using CycloneDX.Spdx.Models.v2_3; - -namespace CycloneDX.Spdx.Interop.Helpers -{ - public static class Files - { - public static List GetSpdxFiles(this Bom bom) - { - List files = null; - if (bom.Components != null && bom.Components.Exists(c => c.Type == Component.Classification.File)) - { - files = new List(); - foreach (var component in bom.Components.Where(c => c.Type == Component.Classification.File)) - { - var file = new File - { - FileName = component.Name, - - SPDXID = component.Properties?.GetSpdxElement(PropertyTaxonomy.SPDXID), - Comment = component.Properties?.GetSpdxElement(PropertyTaxonomy.COMMENT), - Annotations = component.Properties?.GetSpdxElements(PropertyTaxonomy.ANNOTATION), - LicenseComments = component.Properties?.GetSpdxElement(PropertyTaxonomy.LICENSE_COMMENTS), - AttributionTexts = component.GetSpdxAttributionTexts(), - FileContributors = component.Properties?.GetSpdxElements( PropertyTaxonomy.FILE_CONTRIBUTOR), - NoticeText = component.Properties?.GetSpdxElement(PropertyTaxonomy.FILE_NOTICE_TEXT), - }; - - var copyrightText = component.Copyright; - if (!String.IsNullOrEmpty(copyrightText) && copyrightText != "NOASSERTION") - { - file.CopyrightText = copyrightText; - } - - var licenseConcluded = component.Properties?.GetSpdxElement(PropertyTaxonomy.LICENSE_CONCLUDED); - if (!String.IsNullOrEmpty(licenseConcluded) && licenseConcluded != "NOASSERTION") - { - file.LicenseConcluded = licenseConcluded; - } - - if (file.SPDXID == null) - { - if (component.BomRef == null) - { - file.SPDXID = "SPDXRef-File-" + (files.Count + 1).ToString(); - } - else - { - file.SPDXID = $"SPDXRef-{component.BomRef}"; - } - } - - if (component.Properties != null && component.Properties.Exists(p => p.Name == PropertyTaxonomy.FILE_TYPE)) - { - file.FileTypes = new List(); - foreach (var fileType in component.Properties.Where(p => p.Name == PropertyTaxonomy.FILE_TYPE)) - { - var fileTypeEnum = (FileType)Enum.Parse(typeof(FileType), fileType.Value); - file.FileTypes.Add(fileTypeEnum); - } - } - - file.Checksums = component.GetSpdxChecksums(); - - files.Add(file); - } - } - return files; - } - - public static void AddSpdxFiles(this Bom bom, List files) - { - if (files != null && files.Count > 0) - { - if (bom.Components == null) bom.Components = new List(); - foreach (var file in files) - { - var component = new Component - { - Type = Component.Classification.File, - Name = file.FileName, - Copyright = file.CopyrightText, - Properties = new List(), - }; - - component.Properties.AddSpdxElement(PropertyTaxonomy.SPDXID, file.SPDXID); - component.Properties.AddSpdxElement(PropertyTaxonomy.COMMENT, file.Comment); - component.Properties.AddSpdxElements(PropertyTaxonomy.FILE_TYPE, file.FileTypes); - component.Properties.AddSpdxElements(PropertyTaxonomy.ANNOTATION, file.Annotations); - component.Properties.AddSpdxElement(PropertyTaxonomy.LICENSE_COMMENTS, file.LicenseComments); - component.Properties.AddSpdxElement(PropertyTaxonomy.LICENSE_CONCLUDED, file.LicenseConcluded); - component.Properties.AddSpdxElements(PropertyTaxonomy.FILE_CONTRIBUTOR, file.FileContributors); - component.Properties.AddSpdxElement(PropertyTaxonomy.FILE_NOTICE_TEXT, file.NoticeText); - - component.AddSpdxAttributionTexts(file.AttributionTexts); - component.AddSpdxChecksums(file.Checksums); - - bom.Components.Add(component); - } - } - } - } -} +// This file is part of CycloneDX Library for .NET +// +// Licensed under the Apache License, Version 2.0 (the “License”); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an “AS IS” BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) OWASP Foundation. All Rights Reserved. + +using System; +using System.Collections.Generic; +using System.Linq; +using CycloneDX.Models; +using CycloneDX.Spdx.Models.v2_3; + +namespace CycloneDX.Spdx.Interop.Helpers +{ + public static class Files + { + public static List GetSpdxFiles(this Bom bom) + { + List files = null; + if (bom.Components != null && bom.Components.Exists(c => c.Type == Component.Classification.File)) + { + files = new List(); + foreach (var component in bom.Components.Where(c => c.Type == Component.Classification.File)) + { + var file = new File + { + FileName = component.Name, + + SPDXID = component.Properties?.GetSpdxElement(PropertyTaxonomy.SPDXID), + Comment = component.Properties?.GetSpdxElement(PropertyTaxonomy.COMMENT), + Annotations = component.Properties?.GetSpdxElements(PropertyTaxonomy.ANNOTATION), + LicenseComments = component.Properties?.GetSpdxElement(PropertyTaxonomy.LICENSE_COMMENTS), + AttributionTexts = component.GetSpdxAttributionTexts(), + FileContributors = component.Properties?.GetSpdxElements( PropertyTaxonomy.FILE_CONTRIBUTOR), + NoticeText = component.Properties?.GetSpdxElement(PropertyTaxonomy.FILE_NOTICE_TEXT), + }; + + var copyrightText = component.Copyright; + if (!String.IsNullOrEmpty(copyrightText) && copyrightText != "NOASSERTION") + { + file.CopyrightText = copyrightText; + } + + var licenseConcluded = component.Properties?.GetSpdxElement(PropertyTaxonomy.LICENSE_CONCLUDED); + if (!String.IsNullOrEmpty(licenseConcluded) && licenseConcluded != "NOASSERTION") + { + file.LicenseConcluded = licenseConcluded; + } + + if (file.SPDXID == null) + { + if (component.BomRef == null) + { + file.SPDXID = "SPDXRef-File-" + (files.Count + 1).ToString(); + } + else + { + file.SPDXID = $"SPDXRef-{component.BomRef}"; + } + } + + if (component.Properties != null && component.Properties.Exists(p => p.Name == PropertyTaxonomy.FILE_TYPE)) + { + file.FileTypes = new List(); + foreach (var fileType in component.Properties.Where(p => p.Name == PropertyTaxonomy.FILE_TYPE)) + { + var fileTypeEnum = (FileType)Enum.Parse(typeof(FileType), fileType.Value); + file.FileTypes.Add(fileTypeEnum); + } + } + + file.Checksums = component.GetSpdxChecksums(); + + files.Add(file); + } + } + return files; + } + + public static void AddSpdxFiles(this Bom bom, List files) + { + if (files != null && files.Count > 0) + { + if (bom.Components == null) bom.Components = new List(); + foreach (var file in files) + { + var component = new Component + { + Type = Component.Classification.File, + Name = file.FileName, + Copyright = file.CopyrightText, + Properties = new List(), + }; + + component.Properties.AddSpdxElement(PropertyTaxonomy.SPDXID, file.SPDXID); + component.Properties.AddSpdxElement(PropertyTaxonomy.COMMENT, file.Comment); + component.Properties.AddSpdxElements(PropertyTaxonomy.FILE_TYPE, file.FileTypes); + component.Properties.AddSpdxElements(PropertyTaxonomy.ANNOTATION, file.Annotations); + component.Properties.AddSpdxElement(PropertyTaxonomy.LICENSE_COMMENTS, file.LicenseComments); + component.Properties.AddSpdxElement(PropertyTaxonomy.LICENSE_CONCLUDED, file.LicenseConcluded); + component.Properties.AddSpdxElements(PropertyTaxonomy.FILE_CONTRIBUTOR, file.FileContributors); + component.Properties.AddSpdxElement(PropertyTaxonomy.FILE_NOTICE_TEXT, file.NoticeText); + + component.AddSpdxAttributionTexts(file.AttributionTexts); + component.AddSpdxChecksums(file.Checksums); + + bom.Components.Add(component); + } + } + } + } +} diff --git a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Component/AttributionTexts.cs b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Component/AttributionTexts.cs similarity index 97% rename from src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Component/AttributionTexts.cs rename to src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Component/AttributionTexts.cs index cbe7f49b..9cf80b6b 100644 --- a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Component/AttributionTexts.cs +++ b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Component/AttributionTexts.cs @@ -1,59 +1,59 @@ -// This file is part of CycloneDX Library for .NET -// -// Licensed under the Apache License, Version 2.0 (the “License”); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an “AS IS” BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -// Copyright (c) OWASP Foundation. All Rights Reserved. - -using System; -using System.Collections.Generic; -using CycloneDX.Models; - -namespace CycloneDX.Spdx.Interop.Helpers -{ - public static class AttributionTexts - { - public static List GetSpdxAttributionTexts(this Component component) - { - if (component.Evidence?.Copyright != null) - { - var texts = new List(); - foreach (var copyright in component.Evidence.Copyright) - { - texts.Add(copyright.Text); - } - return texts; - } - else - { - return null; - } - } - - public static void AddSpdxAttributionTexts(this Component component, List attributionTexts) - { - if (attributionTexts != null) - { - if (component.Evidence == null) { component.Evidence = new Evidence(); } - if (component.Evidence.Copyright == null) { component.Evidence.Copyright = new List(); } - foreach (var attribution in attributionTexts) - { - component.Evidence.Copyright.Add(new EvidenceCopyright - { - Text = attribution, - }); - } - } - } - } -} +// This file is part of CycloneDX Library for .NET +// +// Licensed under the Apache License, Version 2.0 (the “License”); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an “AS IS” BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) OWASP Foundation. All Rights Reserved. + +using System; +using System.Collections.Generic; +using CycloneDX.Models; + +namespace CycloneDX.Spdx.Interop.Helpers +{ + public static class AttributionTexts + { + public static List GetSpdxAttributionTexts(this Component component) + { + if (component.Evidence?.Copyright != null) + { + var texts = new List(); + foreach (var copyright in component.Evidence.Copyright) + { + texts.Add(copyright.Text); + } + return texts; + } + else + { + return null; + } + } + + public static void AddSpdxAttributionTexts(this Component component, List attributionTexts) + { + if (attributionTexts != null) + { + if (component.Evidence == null) { component.Evidence = new Evidence(); } + if (component.Evidence.Copyright == null) { component.Evidence.Copyright = new List(); } + foreach (var attribution in attributionTexts) + { + component.Evidence.Copyright.Add(new EvidenceCopyright + { + Text = attribution, + }); + } + } + } + } +} diff --git a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Component/Checksums.cs b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Component/Checksums.cs similarity index 97% rename from src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Component/Checksums.cs rename to src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Component/Checksums.cs index 2f97e691..2761062a 100644 --- a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Component/Checksums.cs +++ b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Component/Checksums.cs @@ -1,288 +1,288 @@ -// This file is part of CycloneDX Library for .NET -// -// Licensed under the Apache License, Version 2.0 (the “License”); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an “AS IS” BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -// Copyright (c) OWASP Foundation. All Rights Reserved. - -using System; -using System.Collections.Generic; -using System.Linq; -using CycloneDX.Models; -using CycloneDX.Spdx.Models.v2_3; - -namespace CycloneDX.Spdx.Interop.Helpers -{ - public static class Checksums - { - public static List GetSpdxChecksums(this Component component) - { - var checksums = new List(); - - if (component.Hashes != null && component.Hashes.Count > 0) - { - foreach (var hash in component.Hashes) - { - switch (hash.Alg) - { - case Hash.HashAlgorithm.SHA_1: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.SHA1, - ChecksumValue = hash.Content, - }); - break; - case Hash.HashAlgorithm.SHA_256: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.SHA256, - ChecksumValue = hash.Content, - }); - break; - case Hash.HashAlgorithm.SHA_384: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.SHA384, - ChecksumValue = hash.Content, - }); - break; - case Hash.HashAlgorithm.SHA_512: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.SHA512, - ChecksumValue = hash.Content, - }); - break; - case Hash.HashAlgorithm.MD5: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.MD5, - ChecksumValue = hash.Content, - }); - break; - case Hash.HashAlgorithm.SHA3_256: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.SHA3_256, - ChecksumValue = hash.Content, - }); - break; - case Hash.HashAlgorithm.SHA3_384: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.SHA3_384, - ChecksumValue = hash.Content, - }); - break; - case Hash.HashAlgorithm.SHA3_512: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.SHA3_512, - ChecksumValue = hash.Content, - }); - break; - case Hash.HashAlgorithm.BLAKE2b_256: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.BLAKE2b_256, - ChecksumValue = hash.Content, - }); - break; - case Hash.HashAlgorithm.BLAKE2b_384: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.BLAKE2b_384, - ChecksumValue = hash.Content, - }); - break; - case Hash.HashAlgorithm.BLAKE2b_512: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.BLAKE2b_512, - ChecksumValue = hash.Content, - }); - break; - case Hash.HashAlgorithm.BLAKE3: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.BLAKE3, - ChecksumValue = hash.Content, - }); - break; - } - } - } - - if (component.Properties != null && component.Properties.Exists(p => p.Name.StartsWith(PropertyTaxonomy.CHECKSUM))) - { - foreach (var checksum in component.Properties.Where(p => p.Name.StartsWith(PropertyTaxonomy.CHECKSUM))) - { - switch (checksum.Name) - { - case PropertyTaxonomy.CHECKSUM_SHA224: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.SHA224, - ChecksumValue = checksum.Value, - }); - break; - case PropertyTaxonomy.CHECKSUM_MD2: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.MD2, - ChecksumValue = checksum.Value, - }); - break; - case PropertyTaxonomy.CHECKSUM_MD4: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.MD4, - ChecksumValue = checksum.Value, - }); - break; - case PropertyTaxonomy.CHECKSUM_MD6: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.MD6, - ChecksumValue = checksum.Value, - }); - break; - case PropertyTaxonomy.CHECKSUM_ADLER32: - checksums.Add(new Checksum - { - Algorithm = ChecksumAlgorithm.ADLER32, - ChecksumValue = checksum.Value, - }); - break; - } - } - } - - return checksums.Count == 0 ? null : checksums; - } - - public static void AddSpdxChecksums(this Component component, List checksums) - { - if (checksums != null && checksums.Count > 0) - { - if (component.Properties == null) component.Properties = new List(); - if (component.Hashes == null) component.Hashes = new List(); - foreach (var checksum in checksums) - { - switch (checksum.Algorithm) - { - case ChecksumAlgorithm.SHA1: - component.Hashes.Add(new Hash - { - Alg = Hash.HashAlgorithm.SHA_1, - Content = checksum.ChecksumValue, - }); - break; - case ChecksumAlgorithm.SHA224: - component.Properties.AddSpdxElement(PropertyTaxonomy.CHECKSUM_SHA224, checksum.ChecksumValue); - break; - case ChecksumAlgorithm.SHA256: - component.Hashes.Add(new Hash - { - Alg = Hash.HashAlgorithm.SHA_256, - Content = checksum.ChecksumValue, - }); - break; - case ChecksumAlgorithm.SHA384: - component.Hashes.Add(new Hash - { - Alg = Hash.HashAlgorithm.SHA_384, - Content = checksum.ChecksumValue, - }); - break; - case ChecksumAlgorithm.SHA512: - component.Hashes.Add(new Hash - { - Alg = Hash.HashAlgorithm.SHA_512, - Content = checksum.ChecksumValue, - }); - break; - case ChecksumAlgorithm.MD2: - component.Properties.AddSpdxElement(PropertyTaxonomy.CHECKSUM_MD2, checksum.ChecksumValue); - break; - case ChecksumAlgorithm.MD4: - component.Properties.AddSpdxElement(PropertyTaxonomy.CHECKSUM_MD4, checksum.ChecksumValue); - break; - case ChecksumAlgorithm.MD5: - component.Hashes.Add(new Hash - { - Alg = Hash.HashAlgorithm.MD5, - Content = checksum.ChecksumValue, - }); - break; - case ChecksumAlgorithm.MD6: - component.Properties.AddSpdxElement(PropertyTaxonomy.CHECKSUM_MD6, checksum.ChecksumValue); - break; - case ChecksumAlgorithm.SHA3_256: - component.Hashes.Add(new Hash - { - Alg = Hash.HashAlgorithm.SHA3_256, - Content = checksum.ChecksumValue, - }); - break; - case ChecksumAlgorithm.SHA3_384: - component.Hashes.Add(new Hash - { - Alg = Hash.HashAlgorithm.SHA3_384, - Content = checksum.ChecksumValue, - }); - break; - case ChecksumAlgorithm.SHA3_512: - component.Hashes.Add(new Hash - { - Alg = Hash.HashAlgorithm.SHA3_512, - Content = checksum.ChecksumValue, - }); - break; - case ChecksumAlgorithm.BLAKE2b_256: - component.Hashes.Add(new Hash - { - Alg = Hash.HashAlgorithm.BLAKE2b_256, - Content = checksum.ChecksumValue, - }); - break; - case ChecksumAlgorithm.BLAKE2b_384: - component.Hashes.Add(new Hash - { - Alg = Hash.HashAlgorithm.BLAKE2b_384, - Content = checksum.ChecksumValue, - }); - break; - case ChecksumAlgorithm.BLAKE2b_512: - component.Hashes.Add(new Hash - { - Alg = Hash.HashAlgorithm.BLAKE2b_512, - Content = checksum.ChecksumValue, - }); - break; - case ChecksumAlgorithm.BLAKE3: - component.Hashes.Add(new Hash - { - Alg = Hash.HashAlgorithm.BLAKE3, - Content = checksum.ChecksumValue, - }); - break; - case ChecksumAlgorithm.ADLER32: - component.Properties.AddSpdxElement(PropertyTaxonomy.CHECKSUM_ADLER32, checksum.ChecksumValue); - break; - } - } - } - } - } -} +// This file is part of CycloneDX Library for .NET +// +// Licensed under the Apache License, Version 2.0 (the “License”); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an “AS IS” BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) OWASP Foundation. All Rights Reserved. + +using System; +using System.Collections.Generic; +using System.Linq; +using CycloneDX.Models; +using CycloneDX.Spdx.Models.v2_3; + +namespace CycloneDX.Spdx.Interop.Helpers +{ + public static class Checksums + { + public static List GetSpdxChecksums(this Component component) + { + var checksums = new List(); + + if (component.Hashes != null && component.Hashes.Count > 0) + { + foreach (var hash in component.Hashes) + { + switch (hash.Alg) + { + case Hash.HashAlgorithm.SHA_1: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.SHA1, + ChecksumValue = hash.Content, + }); + break; + case Hash.HashAlgorithm.SHA_256: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.SHA256, + ChecksumValue = hash.Content, + }); + break; + case Hash.HashAlgorithm.SHA_384: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.SHA384, + ChecksumValue = hash.Content, + }); + break; + case Hash.HashAlgorithm.SHA_512: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.SHA512, + ChecksumValue = hash.Content, + }); + break; + case Hash.HashAlgorithm.MD5: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.MD5, + ChecksumValue = hash.Content, + }); + break; + case Hash.HashAlgorithm.SHA3_256: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.SHA3_256, + ChecksumValue = hash.Content, + }); + break; + case Hash.HashAlgorithm.SHA3_384: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.SHA3_384, + ChecksumValue = hash.Content, + }); + break; + case Hash.HashAlgorithm.SHA3_512: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.SHA3_512, + ChecksumValue = hash.Content, + }); + break; + case Hash.HashAlgorithm.BLAKE2b_256: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.BLAKE2b_256, + ChecksumValue = hash.Content, + }); + break; + case Hash.HashAlgorithm.BLAKE2b_384: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.BLAKE2b_384, + ChecksumValue = hash.Content, + }); + break; + case Hash.HashAlgorithm.BLAKE2b_512: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.BLAKE2b_512, + ChecksumValue = hash.Content, + }); + break; + case Hash.HashAlgorithm.BLAKE3: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.BLAKE3, + ChecksumValue = hash.Content, + }); + break; + } + } + } + + if (component.Properties != null && component.Properties.Exists(p => p.Name.StartsWith(PropertyTaxonomy.CHECKSUM))) + { + foreach (var checksum in component.Properties.Where(p => p.Name.StartsWith(PropertyTaxonomy.CHECKSUM))) + { + switch (checksum.Name) + { + case PropertyTaxonomy.CHECKSUM_SHA224: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.SHA224, + ChecksumValue = checksum.Value, + }); + break; + case PropertyTaxonomy.CHECKSUM_MD2: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.MD2, + ChecksumValue = checksum.Value, + }); + break; + case PropertyTaxonomy.CHECKSUM_MD4: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.MD4, + ChecksumValue = checksum.Value, + }); + break; + case PropertyTaxonomy.CHECKSUM_MD6: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.MD6, + ChecksumValue = checksum.Value, + }); + break; + case PropertyTaxonomy.CHECKSUM_ADLER32: + checksums.Add(new Checksum + { + Algorithm = ChecksumAlgorithm.ADLER32, + ChecksumValue = checksum.Value, + }); + break; + } + } + } + + return checksums.Count == 0 ? null : checksums; + } + + public static void AddSpdxChecksums(this Component component, List checksums) + { + if (checksums != null && checksums.Count > 0) + { + if (component.Properties == null) component.Properties = new List(); + if (component.Hashes == null) component.Hashes = new List(); + foreach (var checksum in checksums) + { + switch (checksum.Algorithm) + { + case ChecksumAlgorithm.SHA1: + component.Hashes.Add(new Hash + { + Alg = Hash.HashAlgorithm.SHA_1, + Content = checksum.ChecksumValue, + }); + break; + case ChecksumAlgorithm.SHA224: + component.Properties.AddSpdxElement(PropertyTaxonomy.CHECKSUM_SHA224, checksum.ChecksumValue); + break; + case ChecksumAlgorithm.SHA256: + component.Hashes.Add(new Hash + { + Alg = Hash.HashAlgorithm.SHA_256, + Content = checksum.ChecksumValue, + }); + break; + case ChecksumAlgorithm.SHA384: + component.Hashes.Add(new Hash + { + Alg = Hash.HashAlgorithm.SHA_384, + Content = checksum.ChecksumValue, + }); + break; + case ChecksumAlgorithm.SHA512: + component.Hashes.Add(new Hash + { + Alg = Hash.HashAlgorithm.SHA_512, + Content = checksum.ChecksumValue, + }); + break; + case ChecksumAlgorithm.MD2: + component.Properties.AddSpdxElement(PropertyTaxonomy.CHECKSUM_MD2, checksum.ChecksumValue); + break; + case ChecksumAlgorithm.MD4: + component.Properties.AddSpdxElement(PropertyTaxonomy.CHECKSUM_MD4, checksum.ChecksumValue); + break; + case ChecksumAlgorithm.MD5: + component.Hashes.Add(new Hash + { + Alg = Hash.HashAlgorithm.MD5, + Content = checksum.ChecksumValue, + }); + break; + case ChecksumAlgorithm.MD6: + component.Properties.AddSpdxElement(PropertyTaxonomy.CHECKSUM_MD6, checksum.ChecksumValue); + break; + case ChecksumAlgorithm.SHA3_256: + component.Hashes.Add(new Hash + { + Alg = Hash.HashAlgorithm.SHA3_256, + Content = checksum.ChecksumValue, + }); + break; + case ChecksumAlgorithm.SHA3_384: + component.Hashes.Add(new Hash + { + Alg = Hash.HashAlgorithm.SHA3_384, + Content = checksum.ChecksumValue, + }); + break; + case ChecksumAlgorithm.SHA3_512: + component.Hashes.Add(new Hash + { + Alg = Hash.HashAlgorithm.SHA3_512, + Content = checksum.ChecksumValue, + }); + break; + case ChecksumAlgorithm.BLAKE2b_256: + component.Hashes.Add(new Hash + { + Alg = Hash.HashAlgorithm.BLAKE2b_256, + Content = checksum.ChecksumValue, + }); + break; + case ChecksumAlgorithm.BLAKE2b_384: + component.Hashes.Add(new Hash + { + Alg = Hash.HashAlgorithm.BLAKE2b_384, + Content = checksum.ChecksumValue, + }); + break; + case ChecksumAlgorithm.BLAKE2b_512: + component.Hashes.Add(new Hash + { + Alg = Hash.HashAlgorithm.BLAKE2b_512, + Content = checksum.ChecksumValue, + }); + break; + case ChecksumAlgorithm.BLAKE3: + component.Hashes.Add(new Hash + { + Alg = Hash.HashAlgorithm.BLAKE3, + Content = checksum.ChecksumValue, + }); + break; + case ChecksumAlgorithm.ADLER32: + component.Properties.AddSpdxElement(PropertyTaxonomy.CHECKSUM_ADLER32, checksum.ChecksumValue); + break; + } + } + } + } + } +} diff --git a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Component/ExternalRefs.cs b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Component/ExternalRefs.cs similarity index 98% rename from src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Component/ExternalRefs.cs rename to src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Component/ExternalRefs.cs index 20c7313f..5505a69c 100644 --- a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/Component/ExternalRefs.cs +++ b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/Component/ExternalRefs.cs @@ -1,153 +1,153 @@ -// This file is part of CycloneDX Library for .NET -// -// Licensed under the Apache License, Version 2.0 (the “License”); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an “AS IS” BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -// Copyright (c) OWASP Foundation. All Rights Reserved. - -using System; -using System.Collections.Generic; -using System.Linq; -using CycloneDX.Models; -using CycloneDX.Spdx.Models.v2_3; - -namespace CycloneDX.Spdx.Interop.Helpers -{ - public static class ExternalRefs - { - public static List GetSpdxExternalRefs(this Component component) - { - if (component.Properties == null) - { - return null; - } - var extRefs = new List(); - foreach (var extRefProp in component.Properties.Where(p => p.Name.StartsWith(PropertyTaxonomy.EXTERNAL_REFERENCE))) - { - var extRef = new ExternalRef(); - if (extRefProp.Name.StartsWith(PropertyTaxonomy.EXTERNAL_REFERENCE_OTHER)) - { - extRef.ReferenceCategory = ExternalRefCategory.OTHER; - extRef.ReferenceType = extRefProp.Name.Substring(PropertyTaxonomy.EXTERNAL_REFERENCE_OTHER.Length + 1); - } - else switch (extRefProp.Name) - { - case PropertyTaxonomy.EXTERNAL_REFERENCE_SECURITY_CPE22: - extRef.ReferenceCategory = ExternalRefCategory.SECURITY; - extRef.ReferenceType = "cpe22Type"; - break; - case PropertyTaxonomy.EXTERNAL_REFERENCE_SECURITY_CPE23: - extRef.ReferenceCategory = ExternalRefCategory.SECURITY; - extRef.ReferenceType = "cpe23Type"; - break; - case PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_MAVEN_CENTRAL: - extRef.ReferenceCategory = ExternalRefCategory.PACKAGE_MANAGER; - extRef.ReferenceType = "maven-central"; - break; - case PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_NPM: - extRef.ReferenceCategory = ExternalRefCategory.PACKAGE_MANAGER; - extRef.ReferenceType = "npm"; - break; - case PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_NUGET: - extRef.ReferenceCategory = ExternalRefCategory.PACKAGE_MANAGER; - extRef.ReferenceType = "nuget"; - break; - case PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_BOWER: - extRef.ReferenceCategory = ExternalRefCategory.PACKAGE_MANAGER; - extRef.ReferenceType = "bower"; - break; - case PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_PURL: - extRef.ReferenceCategory = ExternalRefCategory.PACKAGE_MANAGER; - extRef.ReferenceType = "purl"; - break; - //TODO add this back in once the SPDX JSON schema is fixed https://github.com/spdx/spdx-spec/issues/612 - //TODO and write corresponding code in AddExternalRefsToCDX - // case PropertyTaxonomy.EXTERNAL_REFERENCE_PERSISTENT_ID_SWH: - // extRef.ReferenceCategory = ExternalRefCategory.PERSISTENT_ID; - // extRef.ReferenceType = "swh"; - // break; - } - if (extRef.ReferenceType != null) - { - var parts = extRefProp.Value.Split(' '); - extRef.ReferenceLocator = parts[0]; - if (parts.Length > 1) - { - extRef.Comment = String.Join(" ", extRefProp.Value.Split(' ').Skip(1).ToList()); - } - extRefs.Add(extRef); - } - } - return extRefs.Count == 0 ? null : extRefs; - } - - public static void AddSpdxExternalRefs(this Component component, List externalRefs) - { - if (externalRefs != null && externalRefs.Count > 0) - { - if (component.Properties == null) component.Properties = new List(); - foreach (var extRef in externalRefs) - { - string refPropName = null; - if (extRef.ReferenceCategory == ExternalRefCategory.SECURITY) - { - switch (extRef.ReferenceType) - { - case "cpe22Type": - refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_SECURITY_CPE22; - break; - case "cpe23Type": - refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_SECURITY_CPE23; - break; - } - } - else if (extRef.ReferenceCategory == ExternalRefCategory.PACKAGE_MANAGER) - { - switch (extRef.ReferenceType) - { - case "maven-central": - refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_MAVEN_CENTRAL; - break; - case "npm": - refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_NPM; - break; - case "nuget": - refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_NUGET; - break; - case "bower": - refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_BOWER; - break; - case "purl": - refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_PURL; - break; - } - } - else if (extRef.ReferenceCategory == ExternalRefCategory.OTHER) - { - refPropName = $"{PropertyTaxonomy.EXTERNAL_REFERENCE_OTHER}:{extRef.ReferenceType}"; - } - - if (refPropName != null) - { - var refPropValue = extRef.ReferenceLocator; - if (extRef.Comment != null) - { - refPropValue = $"{extRef.ReferenceLocator} {extRef.Comment}"; - } - component.Properties.AddSpdxElement(refPropName, refPropValue); - } - } - } - } - } -} +// This file is part of CycloneDX Library for .NET +// +// Licensed under the Apache License, Version 2.0 (the “License”); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an “AS IS” BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) OWASP Foundation. All Rights Reserved. + +using System; +using System.Collections.Generic; +using System.Linq; +using CycloneDX.Models; +using CycloneDX.Spdx.Models.v2_3; + +namespace CycloneDX.Spdx.Interop.Helpers +{ + public static class ExternalRefs + { + public static List GetSpdxExternalRefs(this Component component) + { + if (component.Properties == null) + { + return null; + } + var extRefs = new List(); + foreach (var extRefProp in component.Properties.Where(p => p.Name.StartsWith(PropertyTaxonomy.EXTERNAL_REFERENCE))) + { + var extRef = new ExternalRef(); + if (extRefProp.Name.StartsWith(PropertyTaxonomy.EXTERNAL_REFERENCE_OTHER)) + { + extRef.ReferenceCategory = ExternalRefCategory.OTHER; + extRef.ReferenceType = extRefProp.Name.Substring(PropertyTaxonomy.EXTERNAL_REFERENCE_OTHER.Length + 1); + } + else switch (extRefProp.Name) + { + case PropertyTaxonomy.EXTERNAL_REFERENCE_SECURITY_CPE22: + extRef.ReferenceCategory = ExternalRefCategory.SECURITY; + extRef.ReferenceType = "cpe22Type"; + break; + case PropertyTaxonomy.EXTERNAL_REFERENCE_SECURITY_CPE23: + extRef.ReferenceCategory = ExternalRefCategory.SECURITY; + extRef.ReferenceType = "cpe23Type"; + break; + case PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_MAVEN_CENTRAL: + extRef.ReferenceCategory = ExternalRefCategory.PACKAGE_MANAGER; + extRef.ReferenceType = "maven-central"; + break; + case PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_NPM: + extRef.ReferenceCategory = ExternalRefCategory.PACKAGE_MANAGER; + extRef.ReferenceType = "npm"; + break; + case PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_NUGET: + extRef.ReferenceCategory = ExternalRefCategory.PACKAGE_MANAGER; + extRef.ReferenceType = "nuget"; + break; + case PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_BOWER: + extRef.ReferenceCategory = ExternalRefCategory.PACKAGE_MANAGER; + extRef.ReferenceType = "bower"; + break; + case PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_PURL: + extRef.ReferenceCategory = ExternalRefCategory.PACKAGE_MANAGER; + extRef.ReferenceType = "purl"; + break; + //TODO add this back in once the SPDX JSON schema is fixed https://github.com/spdx/spdx-spec/issues/612 + //TODO and write corresponding code in AddExternalRefsToCDX + // case PropertyTaxonomy.EXTERNAL_REFERENCE_PERSISTENT_ID_SWH: + // extRef.ReferenceCategory = ExternalRefCategory.PERSISTENT_ID; + // extRef.ReferenceType = "swh"; + // break; + } + if (extRef.ReferenceType != null) + { + var parts = extRefProp.Value.Split(' '); + extRef.ReferenceLocator = parts[0]; + if (parts.Length > 1) + { + extRef.Comment = String.Join(" ", extRefProp.Value.Split(' ').Skip(1).ToList()); + } + extRefs.Add(extRef); + } + } + return extRefs.Count == 0 ? null : extRefs; + } + + public static void AddSpdxExternalRefs(this Component component, List externalRefs) + { + if (externalRefs != null && externalRefs.Count > 0) + { + if (component.Properties == null) component.Properties = new List(); + foreach (var extRef in externalRefs) + { + string refPropName = null; + if (extRef.ReferenceCategory == ExternalRefCategory.SECURITY) + { + switch (extRef.ReferenceType) + { + case "cpe22Type": + refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_SECURITY_CPE22; + break; + case "cpe23Type": + refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_SECURITY_CPE23; + break; + } + } + else if (extRef.ReferenceCategory == ExternalRefCategory.PACKAGE_MANAGER) + { + switch (extRef.ReferenceType) + { + case "maven-central": + refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_MAVEN_CENTRAL; + break; + case "npm": + refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_NPM; + break; + case "nuget": + refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_NUGET; + break; + case "bower": + refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_BOWER; + break; + case "purl": + refPropName = PropertyTaxonomy.EXTERNAL_REFERENCE_PACKAGE_MANAGER_PURL; + break; + } + } + else if (extRef.ReferenceCategory == ExternalRefCategory.OTHER) + { + refPropName = $"{PropertyTaxonomy.EXTERNAL_REFERENCE_OTHER}:{extRef.ReferenceType}"; + } + + if (refPropName != null) + { + var refPropValue = extRef.ReferenceLocator; + if (extRef.Comment != null) + { + refPropValue = $"{extRef.ReferenceLocator} {extRef.Comment}"; + } + component.Properties.AddSpdxElement(refPropName, refPropValue); + } + } + } + } + } +} diff --git a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/CycloneDXBomHelpers.cs b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/CycloneDXBomHelpers.cs similarity index 98% rename from src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/CycloneDXBomHelpers.cs rename to src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/CycloneDXBomHelpers.cs index dee2f986..15d3efcc 100644 --- a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/CycloneDXBomHelpers.cs +++ b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/CycloneDXBomHelpers.cs @@ -1,241 +1,241 @@ -// This file is part of CycloneDX Library for .NET -// -// Licensed under the Apache License, Version 2.0 (the “License”); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an “AS IS” BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -// Copyright (c) OWASP Foundation. All Rights Reserved. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using CycloneDX.Models; -using CycloneDX.Spdx.Models.v2_3; - -namespace CycloneDX.Spdx.Interop.Helpers -{ - public static class CycloneDXBomHelpers - { - public static void AddSpdxPackages(this Bom bom, SpdxDocument doc) - { - if (doc.Packages == null || doc.Packages.Count == 0) { return; } - if (bom.Components == null) bom.Components = new List(); - foreach (var package in doc.Packages) - { - var component = new Component - { - Name = package.Name, - Version = package.VersionInfo, - Copyright = package.CopyrightText, - Description = package.Description, - Properties = new List(), - }; - component.Properties.AddSpdxElement(PropertyTaxonomy.SPDXID, package.SPDXID); - component.Properties.AddSpdxElements(PropertyTaxonomy.ANNOTATION, package.Annotations); - component.Properties.AddSpdxElement(PropertyTaxonomy.FILES_ANALYZED, package.FilesAnalyzed); - component.Properties.AddSpdxElement(PropertyTaxonomy.LICENSE_COMMENTS, package.LicenseComments); - component.Properties.AddSpdxElement(PropertyTaxonomy.LICENSE_CONCLUDED, package.LicenseConcluded); - component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_FILENAME, package.PackageFileName); - component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_VERIFICATION_CODE_VALUE, package.PackageVerificationCode?.PackageVerificationCodeValue); - component.Properties.AddSpdxElements(PropertyTaxonomy.PACKAGE_VERIFICATION_CODE_EXCLUDED_FILE, package.PackageVerificationCode?.PackageVerificationCodeExcludedFiles); - component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_SOURCE_INFO, package.SourceInfo); - component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_SUMMARY, package.Summary); - component.Properties.AddSpdxElement(PropertyTaxonomy.COMMENT, package.Comment); - component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_BUILT_DATE, package.BuiltDate?.ToString("yyyy-MM-ddTHH:mm:ss'Z'")); - component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_RELEASE_DATE, package.ReleaseDate?.ToString("yyyy-MM-ddTHH:mm:ss'Z'")); - component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_VALID_UNTIL_DATE, package.ValidUntilDate?.ToString("yyyy-MM-ddTHH:mm:ss'Z'")); - - //Type - if (package.PrimaryPackagePurpose != null) - { - switch (package.PrimaryPackagePurpose) - { - case PrimaryPackagePurposeType.APPLICATION: - component.Type = Component.Classification.Application; - break; - case PrimaryPackagePurposeType.FIRMWARE: - component.Type = Component.Classification.Firmware; - break; - case PrimaryPackagePurposeType.FRAMEWORK: - component.Type = Component.Classification.Framework; - break; - case PrimaryPackagePurposeType.OPERATING_SYSTEM: - component.Type = Component.Classification.Operating_System; - break; - case PrimaryPackagePurposeType.CONTAINER: - component.Type = Component.Classification.Container; - break; - default: - component.Type = Component.Classification.Library; - break; - } - } - else - { - component.Type = Component.Classification.Library; - } - - - if (package.LicenseInfoFromFiles != null && package.LicenseInfoFromFiles.Count > 0) - { - if (component.Evidence == null) component.Evidence = new Evidence(); - if (component.Evidence.Licenses == null) component.Evidence.Licenses = new List(); - foreach (var licenseInfo in package.LicenseInfoFromFiles) - { - if (licenseInfo.StartsWith("LicenseRef-") - && doc.HasExtractedLicensingInfos != null - && doc.HasExtractedLicensingInfos.Exists(l => l.LicenseId == licenseInfo)) - { - var license = doc.HasExtractedLicensingInfos.First(l => l.LicenseId == licenseInfo); - component.Evidence.Licenses.Add(new LicenseChoice - { - License = new License - { - Name = license.Name, - Text = new AttachedText - { - ContentType = "text/plain", - Encoding = "base64", - Content = license.ExtractedText.Base64Encode(), - }, - Url = license.SeeAlsos?.FirstOrDefault(), - } - }); - } - else if (licenseInfo.StartsWith("LicenseRef-") || licenseInfo.StartsWith("DocumentRef-")) - { - component.Evidence.Licenses.Add(new LicenseChoice - { - License = new License - { - Name = licenseInfo, - } - }); - } - else if (licenseInfo == "NONE" || licenseInfo == "NOASSERTION") - { - // don't do anything for this case - } - else - { - component.Evidence.Licenses.Add(new LicenseChoice - { - License = new License - { - Id = licenseInfo, - } - }); - } - } - } - - if (package.LicenseDeclared == "NOASSERTION") - { - component.Properties.AddSpdxElement(PropertyTaxonomy.LICENSE_DECLARED, package.LicenseDeclared); - } - else if (package.LicenseDeclared == "NONE") - { - component.Licenses = new List(); - } - else - { - component.Licenses = new List { new LicenseChoice { Expression = package.LicenseDeclared } }; - } - - if (package.Originator != null) - { - if (package.Originator == "NOASSERTION") - { - component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR, package.Originator); - } - else - { - var originatorRegex = new Regex(@"(Person|Organization): (?.*) \((?.*)\)"); - var originatorMatch = originatorRegex.Match(package.Originator); - if (originatorMatch.Success) - { - component.Author = originatorMatch.Groups["name"].ToString(); - if (package.Originator.ToLowerInvariant().StartsWith("organization:")) - { - component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR_ORGANIZATION, component.Author); - } - component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR_EMAIL, originatorMatch.Groups["email"].ToString()); - } - } - } - - if (package.Supplier != null) - { - if (package.Supplier == "NOASSERTION") - { - component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_SUPPLIER, package.Supplier); - } - else - { - var supplierRegex = new Regex(@"(Person|Organization): (?.*) \((?.*)\)"); - var supplierMatch = supplierRegex.Match(package.Supplier); - if (supplierMatch.Success) - { - component.Supplier = new OrganizationalEntity - { - Name = supplierMatch.Groups["name"].ToString(), - Contact = new List - { - new OrganizationalContact - { - Email = supplierMatch.Groups["email"].ToString() - } - }, - }; - if (package.Supplier.ToLowerInvariant().StartsWith("organization:")) - { - component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_SUPPLIER_ORGANIZATION, component.Supplier.Name); - } - } - } - } - - component.AddSpdxAttributionTexts(package.AttributionTexts); - component.AddSpdxChecksums(package.Checksums); - component.AddSpdxExternalRefs(package.ExternalRefs); - - if (package.DownloadLocation != null) - { - if (component.ExternalReferences == null) component.ExternalReferences = new List(); - component.ExternalReferences.Add(new ExternalReference - { - Type = ExternalReference.ExternalReferenceType.Distribution, - Url = package.DownloadLocation, - }); - component.Properties.AddSpdxElement(PropertyTaxonomy.DOWNLOAD_LOCATION, package.DownloadLocation); - } - - if (package.Homepage != null) - { - if (component.ExternalReferences == null) component.ExternalReferences = new List(); - component.ExternalReferences.Add(new ExternalReference - { - Type = ExternalReference.ExternalReferenceType.Website, - Url = package.Homepage, - }); - component.Properties.AddSpdxElement(PropertyTaxonomy.HOMEPAGE, package.Homepage); - } - - //TODO HasFile - - bom.Components.Add(component); - } - } - - } -} +// This file is part of CycloneDX Library for .NET +// +// Licensed under the Apache License, Version 2.0 (the “License”); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an “AS IS” BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) OWASP Foundation. All Rights Reserved. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using CycloneDX.Models; +using CycloneDX.Spdx.Models.v2_3; + +namespace CycloneDX.Spdx.Interop.Helpers +{ + public static class CycloneDXBomHelpers + { + public static void AddSpdxPackages(this Bom bom, SpdxDocument doc) + { + if (doc.Packages == null || doc.Packages.Count == 0) { return; } + if (bom.Components == null) bom.Components = new List(); + foreach (var package in doc.Packages) + { + var component = new Component + { + Name = package.Name, + Version = package.VersionInfo, + Copyright = package.CopyrightText, + Description = package.Description, + Properties = new List(), + }; + component.Properties.AddSpdxElement(PropertyTaxonomy.SPDXID, package.SPDXID); + component.Properties.AddSpdxElements(PropertyTaxonomy.ANNOTATION, package.Annotations); + component.Properties.AddSpdxElement(PropertyTaxonomy.FILES_ANALYZED, package.FilesAnalyzed); + component.Properties.AddSpdxElement(PropertyTaxonomy.LICENSE_COMMENTS, package.LicenseComments); + component.Properties.AddSpdxElement(PropertyTaxonomy.LICENSE_CONCLUDED, package.LicenseConcluded); + component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_FILENAME, package.PackageFileName); + component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_VERIFICATION_CODE_VALUE, package.PackageVerificationCode?.PackageVerificationCodeValue); + component.Properties.AddSpdxElements(PropertyTaxonomy.PACKAGE_VERIFICATION_CODE_EXCLUDED_FILE, package.PackageVerificationCode?.PackageVerificationCodeExcludedFiles); + component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_SOURCE_INFO, package.SourceInfo); + component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_SUMMARY, package.Summary); + component.Properties.AddSpdxElement(PropertyTaxonomy.COMMENT, package.Comment); + component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_BUILT_DATE, package.BuiltDate?.ToString("yyyy-MM-ddTHH:mm:ss'Z'")); + component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_RELEASE_DATE, package.ReleaseDate?.ToString("yyyy-MM-ddTHH:mm:ss'Z'")); + component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_VALID_UNTIL_DATE, package.ValidUntilDate?.ToString("yyyy-MM-ddTHH:mm:ss'Z'")); + + //Type + if (package.PrimaryPackagePurpose != null) + { + switch (package.PrimaryPackagePurpose) + { + case PrimaryPackagePurposeType.APPLICATION: + component.Type = Component.Classification.Application; + break; + case PrimaryPackagePurposeType.FIRMWARE: + component.Type = Component.Classification.Firmware; + break; + case PrimaryPackagePurposeType.FRAMEWORK: + component.Type = Component.Classification.Framework; + break; + case PrimaryPackagePurposeType.OPERATING_SYSTEM: + component.Type = Component.Classification.Operating_System; + break; + case PrimaryPackagePurposeType.CONTAINER: + component.Type = Component.Classification.Container; + break; + default: + component.Type = Component.Classification.Library; + break; + } + } + else + { + component.Type = Component.Classification.Library; + } + + + if (package.LicenseInfoFromFiles != null && package.LicenseInfoFromFiles.Count > 0) + { + if (component.Evidence == null) component.Evidence = new Evidence(); + if (component.Evidence.Licenses == null) component.Evidence.Licenses = new List(); + foreach (var licenseInfo in package.LicenseInfoFromFiles) + { + if (licenseInfo.StartsWith("LicenseRef-") + && doc.HasExtractedLicensingInfos != null + && doc.HasExtractedLicensingInfos.Exists(l => l.LicenseId == licenseInfo)) + { + var license = doc.HasExtractedLicensingInfos.First(l => l.LicenseId == licenseInfo); + component.Evidence.Licenses.Add(new LicenseChoice + { + License = new License + { + Name = license.Name, + Text = new AttachedText + { + ContentType = "text/plain", + Encoding = "base64", + Content = license.ExtractedText.Base64Encode(), + }, + Url = license.SeeAlsos?.FirstOrDefault(), + } + }); + } + else if (licenseInfo.StartsWith("LicenseRef-") || licenseInfo.StartsWith("DocumentRef-")) + { + component.Evidence.Licenses.Add(new LicenseChoice + { + License = new License + { + Name = licenseInfo, + } + }); + } + else if (licenseInfo == "NONE" || licenseInfo == "NOASSERTION") + { + // don't do anything for this case + } + else + { + component.Evidence.Licenses.Add(new LicenseChoice + { + License = new License + { + Id = licenseInfo, + } + }); + } + } + } + + if (package.LicenseDeclared == "NOASSERTION") + { + component.Properties.AddSpdxElement(PropertyTaxonomy.LICENSE_DECLARED, package.LicenseDeclared); + } + else if (package.LicenseDeclared == "NONE") + { + component.Licenses = new List(); + } + else + { + component.Licenses = new List { new LicenseChoice { Expression = package.LicenseDeclared } }; + } + + if (package.Originator != null) + { + if (package.Originator == "NOASSERTION") + { + component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR, package.Originator); + } + else + { + var originatorRegex = new Regex(@"(Person|Organization): (?.*) \((?.*)\)"); + var originatorMatch = originatorRegex.Match(package.Originator); + if (originatorMatch.Success) + { + component.Author = originatorMatch.Groups["name"].ToString(); + if (package.Originator.ToLowerInvariant().StartsWith("organization:")) + { + component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR_ORGANIZATION, component.Author); + } + component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR_EMAIL, originatorMatch.Groups["email"].ToString()); + } + } + } + + if (package.Supplier != null) + { + if (package.Supplier == "NOASSERTION") + { + component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_SUPPLIER, package.Supplier); + } + else + { + var supplierRegex = new Regex(@"(Person|Organization): (?.*) \((?.*)\)"); + var supplierMatch = supplierRegex.Match(package.Supplier); + if (supplierMatch.Success) + { + component.Supplier = new OrganizationalEntity + { + Name = supplierMatch.Groups["name"].ToString(), + Contact = new List + { + new OrganizationalContact + { + Email = supplierMatch.Groups["email"].ToString() + } + }, + }; + if (package.Supplier.ToLowerInvariant().StartsWith("organization:")) + { + component.Properties.AddSpdxElement(PropertyTaxonomy.PACKAGE_SUPPLIER_ORGANIZATION, component.Supplier.Name); + } + } + } + } + + component.AddSpdxAttributionTexts(package.AttributionTexts); + component.AddSpdxChecksums(package.Checksums); + component.AddSpdxExternalRefs(package.ExternalRefs); + + if (package.DownloadLocation != null) + { + if (component.ExternalReferences == null) component.ExternalReferences = new List(); + component.ExternalReferences.Add(new ExternalReference + { + Type = ExternalReference.ExternalReferenceType.Distribution, + Url = package.DownloadLocation, + }); + component.Properties.AddSpdxElement(PropertyTaxonomy.DOWNLOAD_LOCATION, package.DownloadLocation); + } + + if (package.Homepage != null) + { + if (component.ExternalReferences == null) component.ExternalReferences = new List(); + component.ExternalReferences.Add(new ExternalReference + { + Type = ExternalReference.ExternalReferenceType.Website, + Url = package.Homepage, + }); + component.Properties.AddSpdxElement(PropertyTaxonomy.HOMEPAGE, package.Homepage); + } + + //TODO HasFile + + bom.Components.Add(component); + } + } + + } +} diff --git a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/General.cs b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/General.cs similarity index 97% rename from src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/General.cs rename to src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/General.cs index 0b0ee96b..4cbe8c94 100644 --- a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/General.cs +++ b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/General.cs @@ -1,140 +1,140 @@ -// This file is part of CycloneDX Library for .NET -// -// Licensed under the Apache License, Version 2.0 (the “License”); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an “AS IS” BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -// Copyright (c) OWASP Foundation. All Rights Reserved. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.Json; -using CycloneDX.Models; - -namespace CycloneDX.Spdx.Interop.Helpers -{ - public static class General - { - private static JsonSerializerOptions _jsonOptions = new JsonSerializerOptions - { - WriteIndented = false, - }; - - public static string Base64Encode(this string plainText) { - var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText); - return System.Convert.ToBase64String(plainTextBytes); - } - - public static string Base64Decode(this string base64EncodedData) { - var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData); - return System.Text.Encoding.UTF8.GetString(base64EncodedBytes); - } - - public static void AddSpdxElement(this List properties, string propertyName, string spdxElement) - { - if (spdxElement != null) - { - properties.Add(new Property - { - Name = propertyName, - Value = spdxElement, - }); - } - } - - public static void AddSpdxElements(this List properties, string propertyName, List spdxElements) - { - if (spdxElements != null) - { - foreach (var spdxElement in spdxElements) - { - properties.AddSpdxElement(propertyName, spdxElement); - } - } - } - - public static void AddSpdxElement(this List properties, string propertyName, T spdxElement) - { - if (spdxElement != null) - { - properties.Add(new Property - { - Name = propertyName, - Value = JsonSerializer.Serialize(spdxElement, _jsonOptions), - }); - } - } - - public static void AddSpdxElements(this List properties, string propertyName, List spdxElements) - { - if (spdxElements != null) - { - foreach (var spdxElement in spdxElements) - { - properties.AddSpdxElement(propertyName, spdxElement); - } - } - } - - private static T GetSpdxElement(string value) - { - return JsonSerializer.Deserialize(value, _jsonOptions); - } - - public static string GetSpdxElement(this List properties, string propertyName) - { - var result = properties.GetSpdxElements(propertyName); - return result == null || result.Count == 0 ? null : result.First(); - } - - public static List GetSpdxElements(this List properties, string propertyName) - { - if (properties.Exists(p => p.Name == propertyName)) - { - var spdxElements = new List(); - foreach (var p in properties.Where(p => p.Name == propertyName)) - { - spdxElements.Add(p.Value); - } - return spdxElements.Count > 0 ? spdxElements : null; - } - else - { - return null; - } - } - - public static T GetSpdxElement(this List properties, string propertyName) - { - var result = properties.GetSpdxElements(propertyName); - return result == null || result.Count == 0 ? default(T) : result.First(); - } - - public static List GetSpdxElements(this List properties, string propertyName) - { - if (properties.Exists(p => p.Name == propertyName)) - { - var spdxElements = new List(); - foreach (var p in properties.Where(p => p.Name == propertyName)) - { - spdxElements.Add(GetSpdxElement(p.Value)); - } - return spdxElements.Count > 0 ? spdxElements : null; - } - else - { - return null; - } - } - } -} +// This file is part of CycloneDX Library for .NET +// +// Licensed under the Apache License, Version 2.0 (the “License”); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an “AS IS” BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) OWASP Foundation. All Rights Reserved. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using CycloneDX.Models; + +namespace CycloneDX.Spdx.Interop.Helpers +{ + public static class General + { + private static JsonSerializerOptions _jsonOptions = new JsonSerializerOptions + { + WriteIndented = false, + }; + + public static string Base64Encode(this string plainText) { + var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText); + return System.Convert.ToBase64String(plainTextBytes); + } + + public static string Base64Decode(this string base64EncodedData) { + var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData); + return System.Text.Encoding.UTF8.GetString(base64EncodedBytes); + } + + public static void AddSpdxElement(this List properties, string propertyName, string spdxElement) + { + if (spdxElement != null) + { + properties.Add(new Property + { + Name = propertyName, + Value = spdxElement, + }); + } + } + + public static void AddSpdxElements(this List properties, string propertyName, List spdxElements) + { + if (spdxElements != null) + { + foreach (var spdxElement in spdxElements) + { + properties.AddSpdxElement(propertyName, spdxElement); + } + } + } + + public static void AddSpdxElement(this List properties, string propertyName, T spdxElement) + { + if (spdxElement != null) + { + properties.Add(new Property + { + Name = propertyName, + Value = JsonSerializer.Serialize(spdxElement, _jsonOptions), + }); + } + } + + public static void AddSpdxElements(this List properties, string propertyName, List spdxElements) + { + if (spdxElements != null) + { + foreach (var spdxElement in spdxElements) + { + properties.AddSpdxElement(propertyName, spdxElement); + } + } + } + + private static T GetSpdxElement(string value) + { + return JsonSerializer.Deserialize(value, _jsonOptions); + } + + public static string GetSpdxElement(this List properties, string propertyName) + { + var result = properties.GetSpdxElements(propertyName); + return result == null || result.Count == 0 ? null : result.First(); + } + + public static List GetSpdxElements(this List properties, string propertyName) + { + if (properties.Exists(p => p.Name == propertyName)) + { + var spdxElements = new List(); + foreach (var p in properties.Where(p => p.Name == propertyName)) + { + spdxElements.Add(p.Value); + } + return spdxElements.Count > 0 ? spdxElements : null; + } + else + { + return null; + } + } + + public static T GetSpdxElement(this List properties, string propertyName) + { + var result = properties.GetSpdxElements(propertyName); + return result == null || result.Count == 0 ? default(T) : result.First(); + } + + public static List GetSpdxElements(this List properties, string propertyName) + { + if (properties.Exists(p => p.Name == propertyName)) + { + var spdxElements = new List(); + foreach (var p in properties.Where(p => p.Name == propertyName)) + { + spdxElements.Add(GetSpdxElement(p.Value)); + } + return spdxElements.Count > 0 ? spdxElements : null; + } + else + { + return null; + } + } + } +} diff --git a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/SpdxDocumentHelpers.cs b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/SpdxDocumentHelpers.cs similarity index 98% rename from src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/SpdxDocumentHelpers.cs rename to src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/SpdxDocumentHelpers.cs index d81de69b..baed3716 100644 --- a/src/CycloneDX.Spdx.Interop/Converters/v2_2/Helpers/SpdxDocumentHelpers.cs +++ b/src/CycloneDX.Spdx.Interop/Converters/v2_3/Helpers/SpdxDocumentHelpers.cs @@ -1,228 +1,228 @@ -// This file is part of CycloneDX Library for .NET -// -// Licensed under the Apache License, Version 2.0 (the “License”); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an “AS IS” BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -// Copyright (c) OWASP Foundation. All Rights Reserved. - -using System; -using System.Collections.Generic; -using System.Linq; -using CycloneDX.Models; -using CycloneDX.Spdx.Models.v2_3; - -namespace CycloneDX.Spdx.Interop.Helpers -{ - public static class SpdxDocumentHelpers - { - public static bool IsSpdxPackageSupportedComponentType(Component component) - { - return component.Type == Component.Classification.Application - || component.Type == Component.Classification.Firmware - || component.Type == Component.Classification.Framework - || component.Type == Component.Classification.Library - || component.Type == Component.Classification.Operating_System - || component.Type == Component.Classification.Container; - } - - public static void AddCycloneDXComponents(this SpdxDocument doc, Bom bom) - { - if (bom.Components == null || bom.Components.Count == 0) { return; } - doc.Packages = doc.Packages ?? new List(); - foreach (var component in bom.Components.Where(c => IsSpdxPackageSupportedComponentType(c))) - { - var package = new Package - { - Name = component.Name, - VersionInfo = component.Version, - Description = component.Description, - }; - - var copyrightText = component.Copyright; - if (!String.IsNullOrEmpty(copyrightText) && copyrightText != "NOASSERTION") - { - package.CopyrightText = copyrightText; - } - - package.SPDXID = component.Properties?.GetSpdxElement(PropertyTaxonomy.SPDXID); - if (package.SPDXID == null) - { - if (component.BomRef == null) - { - package.SPDXID = "SPDXRef-Package-" + (doc.Packages.Count + 1).ToString(); - } - else - { - package.SPDXID = $"SPDXRef-{component.BomRef}"; - } - } - package.Annotations = component.Properties?.GetSpdxElements(PropertyTaxonomy.ANNOTATION); - package.FilesAnalyzed = component.Properties?.GetSpdxElement(PropertyTaxonomy.FILES_ANALYZED); - package.LicenseComments = component.Properties?.GetSpdxElement(PropertyTaxonomy.LICENSE_COMMENTS); - - package.PackageFileName = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_FILENAME); - - var licenseConcluded = component.Properties?.GetSpdxElement(PropertyTaxonomy.LICENSE_CONCLUDED); - if (!String.IsNullOrEmpty(licenseConcluded) && licenseConcluded != "NOASSERTION") - { - package.LicenseConcluded = licenseConcluded; - } - - var builtDate = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_BUILT_DATE); - if ( ! String.IsNullOrEmpty(builtDate)) - { - package.BuiltDate = DateTime.Parse(builtDate.Trim('"')); - } - - var releaseDate = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_RELEASE_DATE); - if ( ! String.IsNullOrEmpty(releaseDate)) - { - package.ReleaseDate = DateTime.Parse(releaseDate.Trim('"')); - } - - var validUntilDate = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_VALID_UNTIL_DATE); - if ( ! String.IsNullOrEmpty(validUntilDate)) - { - package.ValidUntilDate = DateTime.Parse(validUntilDate.Trim('"')); - } - - var packageVerificationCode = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_VERIFICATION_CODE_VALUE); - if (packageVerificationCode != null) - { - package.PackageVerificationCode = new PackageVerificationCode - { - PackageVerificationCodeValue = packageVerificationCode, - PackageVerificationCodeExcludedFiles = component.Properties?.GetSpdxElements(PropertyTaxonomy.PACKAGE_VERIFICATION_CODE_EXCLUDED_FILE), - }; - } - package.SourceInfo = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_SOURCE_INFO); - package.Summary = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_SUMMARY); - package.Comment = component.Properties?.GetSpdxElement(PropertyTaxonomy.COMMENT); - - // LicenseInfoFromFiles - if (component.Evidence?.Licenses != null && component.Evidence.Licenses.Count > 0) - { - if (package.LicenseInfoFromFiles == null) package.LicenseInfoFromFiles = new List(); - foreach (var license in component.Evidence.Licenses) - { - if (license.Expression != null) - { - // TODO revisit this after some sleep - // at first glance it doesn't look like expressions are handled in ExtractedLicensingInfo - } - else if (license.License != null) - { - if (license.License.Id != null) - { - package.LicenseInfoFromFiles.Add(license.License.Id); - } - else - { - if (doc.HasExtractedLicensingInfos == null) doc.HasExtractedLicensingInfos = new List(); - var extLicInfo = new ExtractedLicensingInfo - { - LicenseId = $"LicenseRef-{doc.HasExtractedLicensingInfos.Count + 1}", - Name = license.License.Name, - SeeAlsos = license.License.Url == null ? null : new List { license.License.Url }, - ExtractedText = license.License.Text?.Content?.Base64Decode(), - }; - doc.HasExtractedLicensingInfos.Add(extLicInfo); - package.LicenseInfoFromFiles.Add(extLicInfo.LicenseId); - } - } - } - } - - // LicenseDeclared - var licenseDeclared = component.Properties?.GetSpdxElement(PropertyTaxonomy.LICENSE_DECLARED); - if (!String.IsNullOrEmpty(licenseDeclared) && licenseDeclared != "NOASSERTION") - { - package.LicenseDeclared = licenseDeclared; - } - - if (component.Licenses != null && component.Licenses.Count == 1) - { - - package.LicenseDeclared = component.Licenses.First().Expression ?? component.Licenses.First().License.Id; - } - - - - // Package Originator - package.Originator = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR); - if (component.Author != null) - { - if (component.Author == component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR_ORGANIZATION)) - { - package.Originator = $"Organization: {component.Author} ({component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR_EMAIL) ?? ""})"; - } - else - { - package.Originator = $"Person: {component.Author} ({component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR_EMAIL) ?? ""})"; - } - } - - package.Supplier = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_SUPPLIER); - if (component.Supplier != null) - { - var supplierEmails = component.Supplier.Contact.Where(c => c.Email != null).ToList(); - var supplierEmail = supplierEmails.Count > 0 ? supplierEmails.First().Email : ""; - if (component.Supplier.Name == component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_SUPPLIER_ORGANIZATION)) - { - package.Supplier = $"Organization: {component.Supplier.Name} ({supplierEmail})"; - } - else - { - package.Supplier = $"Person: {component.Supplier.Name} ({supplierEmail})"; - } - } - - package.AttributionTexts = component.GetSpdxAttributionTexts(); - - package.Checksums = component.GetSpdxChecksums(); - package.ExternalRefs = component.GetSpdxExternalRefs(); - - package.DownloadLocation = component.Properties?.GetSpdxElement(PropertyTaxonomy.DOWNLOAD_LOCATION) ?? "NOASSERTION"; - package.Homepage = component.Properties?.GetSpdxElement(PropertyTaxonomy.HOMEPAGE) ?? "NOASSERTION"; - - //PrimaryPackagePurpose - switch (component.Type) - { - case Component.Classification.Application: - package.PrimaryPackagePurpose = PrimaryPackagePurposeType.APPLICATION; - break; - case Component.Classification.Firmware: - package.PrimaryPackagePurpose = PrimaryPackagePurposeType.FIRMWARE; - break; - case Component.Classification.Framework: - package.PrimaryPackagePurpose = PrimaryPackagePurposeType.FRAMEWORK; - break; - - case Component.Classification.Operating_System: - package.PrimaryPackagePurpose = PrimaryPackagePurposeType.OPERATING_SYSTEM; - break; - case Component.Classification.Container: - package.PrimaryPackagePurpose = PrimaryPackagePurposeType.CONTAINER; - break; - default: - package.PrimaryPackagePurpose = PrimaryPackagePurposeType.LIBRARY; - break; - } - - //TODO HasFile - - doc.Packages.Add(package); - } - } - } -} +// This file is part of CycloneDX Library for .NET +// +// Licensed under the Apache License, Version 2.0 (the “License”); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an “AS IS” BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) OWASP Foundation. All Rights Reserved. + +using System; +using System.Collections.Generic; +using System.Linq; +using CycloneDX.Models; +using CycloneDX.Spdx.Models.v2_3; + +namespace CycloneDX.Spdx.Interop.Helpers +{ + public static class SpdxDocumentHelpers + { + public static bool IsSpdxPackageSupportedComponentType(Component component) + { + return component.Type == Component.Classification.Application + || component.Type == Component.Classification.Firmware + || component.Type == Component.Classification.Framework + || component.Type == Component.Classification.Library + || component.Type == Component.Classification.Operating_System + || component.Type == Component.Classification.Container; + } + + public static void AddCycloneDXComponents(this SpdxDocument doc, Bom bom) + { + if (bom.Components == null || bom.Components.Count == 0) { return; } + doc.Packages = doc.Packages ?? new List(); + foreach (var component in bom.Components.Where(c => IsSpdxPackageSupportedComponentType(c))) + { + var package = new Package + { + Name = component.Name, + VersionInfo = component.Version, + Description = component.Description, + }; + + var copyrightText = component.Copyright; + if (!String.IsNullOrEmpty(copyrightText) && copyrightText != "NOASSERTION") + { + package.CopyrightText = copyrightText; + } + + package.SPDXID = component.Properties?.GetSpdxElement(PropertyTaxonomy.SPDXID); + if (package.SPDXID == null) + { + if (component.BomRef == null) + { + package.SPDXID = "SPDXRef-Package-" + (doc.Packages.Count + 1).ToString(); + } + else + { + package.SPDXID = $"SPDXRef-{component.BomRef}"; + } + } + package.Annotations = component.Properties?.GetSpdxElements(PropertyTaxonomy.ANNOTATION); + package.FilesAnalyzed = component.Properties?.GetSpdxElement(PropertyTaxonomy.FILES_ANALYZED); + package.LicenseComments = component.Properties?.GetSpdxElement(PropertyTaxonomy.LICENSE_COMMENTS); + + package.PackageFileName = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_FILENAME); + + var licenseConcluded = component.Properties?.GetSpdxElement(PropertyTaxonomy.LICENSE_CONCLUDED); + if (!String.IsNullOrEmpty(licenseConcluded) && licenseConcluded != "NOASSERTION") + { + package.LicenseConcluded = licenseConcluded; + } + + var builtDate = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_BUILT_DATE); + if ( ! String.IsNullOrEmpty(builtDate)) + { + package.BuiltDate = DateTime.Parse(builtDate.Trim('"')); + } + + var releaseDate = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_RELEASE_DATE); + if ( ! String.IsNullOrEmpty(releaseDate)) + { + package.ReleaseDate = DateTime.Parse(releaseDate.Trim('"')); + } + + var validUntilDate = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_VALID_UNTIL_DATE); + if ( ! String.IsNullOrEmpty(validUntilDate)) + { + package.ValidUntilDate = DateTime.Parse(validUntilDate.Trim('"')); + } + + var packageVerificationCode = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_VERIFICATION_CODE_VALUE); + if (packageVerificationCode != null) + { + package.PackageVerificationCode = new PackageVerificationCode + { + PackageVerificationCodeValue = packageVerificationCode, + PackageVerificationCodeExcludedFiles = component.Properties?.GetSpdxElements(PropertyTaxonomy.PACKAGE_VERIFICATION_CODE_EXCLUDED_FILE), + }; + } + package.SourceInfo = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_SOURCE_INFO); + package.Summary = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_SUMMARY); + package.Comment = component.Properties?.GetSpdxElement(PropertyTaxonomy.COMMENT); + + // LicenseInfoFromFiles + if (component.Evidence?.Licenses != null && component.Evidence.Licenses.Count > 0) + { + if (package.LicenseInfoFromFiles == null) package.LicenseInfoFromFiles = new List(); + foreach (var license in component.Evidence.Licenses) + { + if (license.Expression != null) + { + // TODO revisit this after some sleep + // at first glance it doesn't look like expressions are handled in ExtractedLicensingInfo + } + else if (license.License != null) + { + if (license.License.Id != null) + { + package.LicenseInfoFromFiles.Add(license.License.Id); + } + else + { + if (doc.HasExtractedLicensingInfos == null) doc.HasExtractedLicensingInfos = new List(); + var extLicInfo = new ExtractedLicensingInfo + { + LicenseId = $"LicenseRef-{doc.HasExtractedLicensingInfos.Count + 1}", + Name = license.License.Name, + SeeAlsos = license.License.Url == null ? null : new List { license.License.Url }, + ExtractedText = license.License.Text?.Content?.Base64Decode(), + }; + doc.HasExtractedLicensingInfos.Add(extLicInfo); + package.LicenseInfoFromFiles.Add(extLicInfo.LicenseId); + } + } + } + } + + // LicenseDeclared + var licenseDeclared = component.Properties?.GetSpdxElement(PropertyTaxonomy.LICENSE_DECLARED); + if (!String.IsNullOrEmpty(licenseDeclared) && licenseDeclared != "NOASSERTION") + { + package.LicenseDeclared = licenseDeclared; + } + + if (component.Licenses != null && component.Licenses.Count == 1) + { + + package.LicenseDeclared = component.Licenses.First().Expression ?? component.Licenses.First().License.Id; + } + + + + // Package Originator + package.Originator = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR); + if (component.Author != null) + { + if (component.Author == component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR_ORGANIZATION)) + { + package.Originator = $"Organization: {component.Author} ({component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR_EMAIL) ?? ""})"; + } + else + { + package.Originator = $"Person: {component.Author} ({component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_ORIGINATOR_EMAIL) ?? ""})"; + } + } + + package.Supplier = component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_SUPPLIER); + if (component.Supplier != null) + { + var supplierEmails = component.Supplier.Contact.Where(c => c.Email != null).ToList(); + var supplierEmail = supplierEmails.Count > 0 ? supplierEmails.First().Email : ""; + if (component.Supplier.Name == component.Properties?.GetSpdxElement(PropertyTaxonomy.PACKAGE_SUPPLIER_ORGANIZATION)) + { + package.Supplier = $"Organization: {component.Supplier.Name} ({supplierEmail})"; + } + else + { + package.Supplier = $"Person: {component.Supplier.Name} ({supplierEmail})"; + } + } + + package.AttributionTexts = component.GetSpdxAttributionTexts(); + + package.Checksums = component.GetSpdxChecksums(); + package.ExternalRefs = component.GetSpdxExternalRefs(); + + package.DownloadLocation = component.Properties?.GetSpdxElement(PropertyTaxonomy.DOWNLOAD_LOCATION) ?? "NOASSERTION"; + package.Homepage = component.Properties?.GetSpdxElement(PropertyTaxonomy.HOMEPAGE) ?? "NOASSERTION"; + + //PrimaryPackagePurpose + switch (component.Type) + { + case Component.Classification.Application: + package.PrimaryPackagePurpose = PrimaryPackagePurposeType.APPLICATION; + break; + case Component.Classification.Firmware: + package.PrimaryPackagePurpose = PrimaryPackagePurposeType.FIRMWARE; + break; + case Component.Classification.Framework: + package.PrimaryPackagePurpose = PrimaryPackagePurposeType.FRAMEWORK; + break; + + case Component.Classification.Operating_System: + package.PrimaryPackagePurpose = PrimaryPackagePurposeType.OPERATING_SYSTEM; + break; + case Component.Classification.Container: + package.PrimaryPackagePurpose = PrimaryPackagePurposeType.CONTAINER; + break; + default: + package.PrimaryPackagePurpose = PrimaryPackagePurposeType.LIBRARY; + break; + } + + //TODO HasFile + + doc.Packages.Add(package); + } + } + } +} diff --git a/src/CycloneDX.Spdx.Interop/Converters/v2_2/SpdxDocumentConverters.cs b/src/CycloneDX.Spdx.Interop/Converters/v2_3/SpdxDocumentConverters.cs similarity index 97% rename from src/CycloneDX.Spdx.Interop/Converters/v2_2/SpdxDocumentConverters.cs rename to src/CycloneDX.Spdx.Interop/Converters/v2_3/SpdxDocumentConverters.cs index 4dd16e88..1f447e68 100644 --- a/src/CycloneDX.Spdx.Interop/Converters/v2_2/SpdxDocumentConverters.cs +++ b/src/CycloneDX.Spdx.Interop/Converters/v2_3/SpdxDocumentConverters.cs @@ -1,129 +1,129 @@ -// This file is part of CycloneDX Library for .NET -// -// Licensed under the Apache License, Version 2.0 (the “License”); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an “AS IS” BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -// Copyright (c) OWASP Foundation. All Rights Reserved. - -using System; -using System.Collections.Generic; -using CycloneDX.Models; -using CycloneDX.Spdx.Models.v2_3; -using CycloneDX.Spdx.Interop.Helpers; - -namespace CycloneDX.Spdx.Interop -{ - public static class SpdxDocumentConverters - { - public static SpdxDocument ToSpdx(this Bom bom) - { - var doc = new SpdxDocument() - { - CreationInfo = new CreationInfo(), - }; - - // document - doc.SPDXID = bom?.Metadata?.Properties?.GetSpdxElement(PropertyTaxonomy.SPDXID) ?? "SPDXRef-DOCUMENT"; - doc.Comment = bom?.Metadata?.Properties?.GetSpdxElement(PropertyTaxonomy.COMMENT); - - doc.Name = bom?.Metadata?.Properties?.GetSpdxElement(PropertyTaxonomy.DOCUMENT_NAME); - if (doc.Name == null) - { - if (bom.Metadata?.Component?.Name != null) - { - doc.Name = bom.Metadata.Component.Name; - if (bom.Metadata.Component.Version != null) { doc.Name += $"-{bom.Metadata.Component.Version}"; } - if (bom.Metadata.Component.Group != null) { doc.Name = $"{bom.Metadata.Component.Group} {doc.Name}"; } - } - else - { - doc.Name = "CycloneDX BOM"; - } - } - - doc.DocumentNamespace = bom?.Metadata?.Properties?.GetSpdxElement(PropertyTaxonomy.DOCUMENT_NAMESPACE); - if (doc.DocumentNamespace == null) - { - string docId; - if (string.IsNullOrEmpty(bom.SerialNumber)) - { - docId = Guid.NewGuid().ToString(); - } - else if (bom.SerialNumber.StartsWith("urn:uuid:", StringComparison.InvariantCulture)) - { - docId = bom.SerialNumber.Remove(0, 9); - } - else - { - docId = bom.SerialNumber; - } - doc.DocumentNamespace = $"http://spdx.org/spdxdocs/{doc.Name}-{docId}"; - } - - // creation info - doc.CreationInfo.Comment = bom.Metadata?.Properties?.GetSpdxElement(PropertyTaxonomy.CREATION_INFO_COMMENT) ?? "This SPDX document has been converted from CycloneDX format."; - doc.CreationInfo.Created = bom.Metadata?.Timestamp != null ? bom.Metadata.Timestamp.Value : DateTime.UtcNow; - doc.CreationInfo.Creators = bom.GetSpdxCreators(); - doc.CreationInfo.LicenseListVersion = bom.Metadata?.Properties?.GetSpdxElement(PropertyTaxonomy.CREATION_INFO_LICENSE_LIST_VERSION); - - doc.ExternalDocumentRefs = bom.Metadata?.Properties?.GetSpdxElements(PropertyTaxonomy.DOCUMENT_EXTERNAL_DOCUMENT_REF); - doc.Annotations = bom.Metadata?.Properties?.GetSpdxElements(PropertyTaxonomy.ANNOTATION); - doc.DocumentDescribes = bom.Metadata?.Properties?.GetSpdxElements(PropertyTaxonomy.DOCUMENT_DESCRIBES); - - doc.AddCycloneDXComponents(bom); - doc.Files = bom.GetSpdxFiles(); - //TODO HasExtractedLicensingInfos - //TODO relationships, assemblies, dependency graph, etc - - return doc; - } - - public static Bom ToCycloneDX(this SpdxDocument doc) - { - var bom = new Bom() - { - Metadata = new Metadata - { - Properties = new List(), - } - }; - - // document - bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.SPDXID, doc.SPDXID); - bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.DOCUMENT_SPDX_VERSION, doc.SpdxVersion); - bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.COMMENT, doc.Comment); - bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.DOCUMENT_NAME, doc.Name); - bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.DOCUMENT_NAMESPACE, doc.DocumentNamespace); - - // creation info - if (doc.CreationInfo != null) - { - bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.CREATION_INFO_COMMENT, doc.CreationInfo.Comment); - bom.Metadata.Timestamp = doc.CreationInfo.Created; - bom.AddSpdxCreators(doc.CreationInfo.Creators); - bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.CREATION_INFO_LICENSE_LIST_VERSION, doc.CreationInfo.LicenseListVersion); - } - - bom.Metadata.Properties.AddSpdxElements(PropertyTaxonomy.DOCUMENT_EXTERNAL_DOCUMENT_REF, doc.ExternalDocumentRefs); - bom.Metadata.Properties.AddSpdxElements(PropertyTaxonomy.ANNOTATION, doc.Annotations); - bom.Metadata.Properties.AddSpdxElements(PropertyTaxonomy.DOCUMENT_DESCRIBES, doc.DocumentDescribes); - - bom.AddSpdxPackages(doc); - bom.AddSpdxFiles(doc.Files); - - return bom; - } - - - } -} +// This file is part of CycloneDX Library for .NET +// +// Licensed under the Apache License, Version 2.0 (the “License”); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an “AS IS” BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) OWASP Foundation. All Rights Reserved. + +using System; +using System.Collections.Generic; +using CycloneDX.Models; +using CycloneDX.Spdx.Models.v2_3; +using CycloneDX.Spdx.Interop.Helpers; + +namespace CycloneDX.Spdx.Interop +{ + public static class SpdxDocumentConverters + { + public static SpdxDocument ToSpdx(this Bom bom) + { + var doc = new SpdxDocument() + { + CreationInfo = new CreationInfo(), + }; + + // document + doc.SPDXID = bom?.Metadata?.Properties?.GetSpdxElement(PropertyTaxonomy.SPDXID) ?? "SPDXRef-DOCUMENT"; + doc.Comment = bom?.Metadata?.Properties?.GetSpdxElement(PropertyTaxonomy.COMMENT); + + doc.Name = bom?.Metadata?.Properties?.GetSpdxElement(PropertyTaxonomy.DOCUMENT_NAME); + if (doc.Name == null) + { + if (bom.Metadata?.Component?.Name != null) + { + doc.Name = bom.Metadata.Component.Name; + if (bom.Metadata.Component.Version != null) { doc.Name += $"-{bom.Metadata.Component.Version}"; } + if (bom.Metadata.Component.Group != null) { doc.Name = $"{bom.Metadata.Component.Group} {doc.Name}"; } + } + else + { + doc.Name = "CycloneDX BOM"; + } + } + + doc.DocumentNamespace = bom?.Metadata?.Properties?.GetSpdxElement(PropertyTaxonomy.DOCUMENT_NAMESPACE); + if (doc.DocumentNamespace == null) + { + string docId; + if (string.IsNullOrEmpty(bom.SerialNumber)) + { + docId = Guid.NewGuid().ToString(); + } + else if (bom.SerialNumber.StartsWith("urn:uuid:", StringComparison.InvariantCulture)) + { + docId = bom.SerialNumber.Remove(0, 9); + } + else + { + docId = bom.SerialNumber; + } + doc.DocumentNamespace = $"http://spdx.org/spdxdocs/{doc.Name}-{docId}"; + } + + // creation info + doc.CreationInfo.Comment = bom.Metadata?.Properties?.GetSpdxElement(PropertyTaxonomy.CREATION_INFO_COMMENT) ?? "This SPDX document has been converted from CycloneDX format."; + doc.CreationInfo.Created = bom.Metadata?.Timestamp != null ? bom.Metadata.Timestamp.Value : DateTime.UtcNow; + doc.CreationInfo.Creators = bom.GetSpdxCreators(); + doc.CreationInfo.LicenseListVersion = bom.Metadata?.Properties?.GetSpdxElement(PropertyTaxonomy.CREATION_INFO_LICENSE_LIST_VERSION); + + doc.ExternalDocumentRefs = bom.Metadata?.Properties?.GetSpdxElements(PropertyTaxonomy.DOCUMENT_EXTERNAL_DOCUMENT_REF); + doc.Annotations = bom.Metadata?.Properties?.GetSpdxElements(PropertyTaxonomy.ANNOTATION); + doc.DocumentDescribes = bom.Metadata?.Properties?.GetSpdxElements(PropertyTaxonomy.DOCUMENT_DESCRIBES); + + doc.AddCycloneDXComponents(bom); + doc.Files = bom.GetSpdxFiles(); + //TODO HasExtractedLicensingInfos + //TODO relationships, assemblies, dependency graph, etc + + return doc; + } + + public static Bom ToCycloneDX(this SpdxDocument doc) + { + var bom = new Bom() + { + Metadata = new Metadata + { + Properties = new List(), + } + }; + + // document + bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.SPDXID, doc.SPDXID); + bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.DOCUMENT_SPDX_VERSION, doc.SpdxVersion); + bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.COMMENT, doc.Comment); + bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.DOCUMENT_NAME, doc.Name); + bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.DOCUMENT_NAMESPACE, doc.DocumentNamespace); + + // creation info + if (doc.CreationInfo != null) + { + bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.CREATION_INFO_COMMENT, doc.CreationInfo.Comment); + bom.Metadata.Timestamp = doc.CreationInfo.Created; + bom.AddSpdxCreators(doc.CreationInfo.Creators); + bom.Metadata.Properties.AddSpdxElement(PropertyTaxonomy.CREATION_INFO_LICENSE_LIST_VERSION, doc.CreationInfo.LicenseListVersion); + } + + bom.Metadata.Properties.AddSpdxElements(PropertyTaxonomy.DOCUMENT_EXTERNAL_DOCUMENT_REF, doc.ExternalDocumentRefs); + bom.Metadata.Properties.AddSpdxElements(PropertyTaxonomy.ANNOTATION, doc.Annotations); + bom.Metadata.Properties.AddSpdxElements(PropertyTaxonomy.DOCUMENT_DESCRIBES, doc.DocumentDescribes); + + bom.AddSpdxPackages(doc); + bom.AddSpdxFiles(doc.Files); + + return bom; + } + + + } +}