diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a560613
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/librhsm-0.0.3.tar.gz
diff --git a/.librhsm.metadata b/.librhsm.metadata
new file mode 100644
index 0000000..fdbe51d
--- /dev/null
+++ b/.librhsm.metadata
@@ -0,0 +1 @@
+72963388eece706d328b84070107e20d322cf0e4 SOURCES/librhsm-0.0.3.tar.gz
diff --git a/SOURCES/0001-Replace-bool-option-with-int-to-generate-repo-files.patch b/SOURCES/0001-Replace-bool-option-with-int-to-generate-repo-files.patch
new file mode 100644
index 0000000..63ecc50
--- /dev/null
+++ b/SOURCES/0001-Replace-bool-option-with-int-to-generate-repo-files.patch
@@ -0,0 +1,35 @@
+From e8ea9f09f4ec718c42b1909e21369a9487ed5f4b Mon Sep 17 00:00:00 2001
+From: Jaroslav Mracek <jmracek@redhat.com>
+Date: Tue, 13 Nov 2018 18:31:57 +0100
+Subject: [PATCH 1/4] Replace bool option with int to generate repo files
+
+During the testing of subscription manager it was discovered that
+subscription manager detects disabled repository by test if key
+"enabled == 0". It means that enabled=false was detected as enabled
+repository. I know that the issue is in subscription manager, but
+keeping the patch is not harmful because the 0/1 is also valid
+combination like false/true.
+---
+ rhsm/rhsm-utils.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/rhsm/rhsm-utils.c b/rhsm/rhsm-utils.c
+index 7b6a26b305515c53e10b9cecb9f95b2e9d84ad02..06b12fca7fe366f42f0daa1e77c275c3a8e9375c 100644
+--- a/rhsm/rhsm-utils.c
++++ b/rhsm/rhsm-utils.c
+@@ -260,11 +260,11 @@ rhsm_utils_yum_repo_from_context (RHSMContext *ctx)
+             }
+ 
+           g_autofree gchar *baseurl = g_strconcat (ctx_baseurl, path, NULL);
+           g_key_file_set_string (repofile, id, "name", name);
+           g_key_file_set_string (repofile, id, "baseurl", baseurl);
+-          g_key_file_set_boolean (repofile, id, "enabled", enabled);
++          g_key_file_set_integer (repofile, id, "enabled", enabled ? 1 : 0);
+ 
+           if (json_object_has_member (repo, "gpg_url"))
+             {
+               const gchar *gpg_url = json_object_get_string_member (repo, "gpg_url");
+               g_key_file_set_string (repofile, id, "gpgkey", gpg_url);
+-- 
+2.26.2
+
diff --git a/SOURCES/0002-Generate-repofile-for-any-architecture-if-ALL-is-spe.patch b/SOURCES/0002-Generate-repofile-for-any-architecture-if-ALL-is-spe.patch
new file mode 100644
index 0000000..0268a83
--- /dev/null
+++ b/SOURCES/0002-Generate-repofile-for-any-architecture-if-ALL-is-spe.patch
@@ -0,0 +1,35 @@
+From e215c12da9b74dbe85e2ca6555fd10b5b02778d5 Mon Sep 17 00:00:00 2001
+From: Pavla Kratochvilova <pkratoch@redhat.com>
+Date: Wed, 20 Mar 2019 18:45:16 +0100
+Subject: [PATCH 2/4] Generate repofile for any architecture if "ALL" is
+ specified (RhBug:1645318)
+
+The "arches" array can contain special value "ALL" and in that case any
+architecture should be accepted.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1645318
+---
+ rhsm/rhsm-utils.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/rhsm/rhsm-utils.c b/rhsm/rhsm-utils.c
+index 06b12fca7fe366f42f0daa1e77c275c3a8e9375c..b52a2b81f3c2ba2f881d7f1746d9e0c0b15ab189 100644
+--- a/rhsm/rhsm-utils.c
++++ b/rhsm/rhsm-utils.c
+@@ -228,11 +228,12 @@ rhsm_utils_yum_repo_from_context (RHSMContext *ctx)
+ 
+           /* Filter by arches vs context one */
+           if (json_object_has_member (repo, "arches"))
+             {
+               JsonArray *arr = json_object_get_array_member (repo, "arches");
+-              if (!rhsm_json_array_contains_string (arr, ctx_arch))
++              if (!rhsm_json_array_contains_string (arr, ctx_arch)
++                && !rhsm_json_array_contains_string (arr, "ALL"))
+                 continue;
+             }
+ 
+           /* Filter by required tags vs available tags */
+           if (json_object_has_member (repo, "required_tags"))
+-- 
+2.26.2
+
diff --git a/SOURCES/0003-Enable-repos-when-generating-a-.repo-file-based-on-e.patch b/SOURCES/0003-Enable-repos-when-generating-a-.repo-file-based-on-e.patch
new file mode 100644
index 0000000..c036c6d
--- /dev/null
+++ b/SOURCES/0003-Enable-repos-when-generating-a-.repo-file-based-on-e.patch
@@ -0,0 +1,40 @@
+From 55e2f2d64372043e2fab96461243d808326bc902 Mon Sep 17 00:00:00 2001
+From: Daniel Mach <dmach@redhat.com>
+Date: Tue, 13 Nov 2018 12:17:58 +0100
+Subject: [PATCH 3/4] Enable repos when generating a .repo file based on
+ entitlement certificate.
+
+Resolves: rhbz#1638850
+---
+ rhsm/rhsm-utils.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/rhsm/rhsm-utils.c b/rhsm/rhsm-utils.c
+index b52a2b81f3c2ba2f881d7f1746d9e0c0b15ab189..6708a43a93f850f873a216d6f20aca8b7bd3225e 100644
+--- a/rhsm/rhsm-utils.c
++++ b/rhsm/rhsm-utils.c
+@@ -245,13 +245,20 @@ rhsm_utils_yum_repo_from_context (RHSMContext *ctx)
+ 
+           /* Now we have only available repos */
+           const gchar *id = json_object_get_string_member (repo, "label");
+           const gchar *name = json_object_get_string_member (repo, "name");
+           const gchar *path = json_object_get_string_member (repo, "path");
+-          gboolean enabled = FALSE;
++
++          /*
++           * The "enabled" option defaults to "true".
++           * If a content (repository) is enabled, the option is missing in the data,
++           * most likely to save limited space in the certificate.
++           */
++          gboolean enabled = TRUE;
+           if (json_object_has_member (repo, "enabled"))
+             enabled = json_object_get_boolean_member (repo, "enabled");
++
+           if (id == NULL || name == NULL || path == NULL)
+             continue; /* TODO: make some error reporting here */
+ 
+           /* Clashing repositories */
+           if (g_key_file_has_group (repofile, id))
+-- 
+2.26.2
+
diff --git a/SOURCES/0004-Append-ctx_baseurl-prefix-to-gpg_url-RhBug-1708628.patch b/SOURCES/0004-Append-ctx_baseurl-prefix-to-gpg_url-RhBug-1708628.patch
new file mode 100644
index 0000000..5f9a250
--- /dev/null
+++ b/SOURCES/0004-Append-ctx_baseurl-prefix-to-gpg_url-RhBug-1708628.patch
@@ -0,0 +1,138 @@
+From 966d9e6b0dec88020a5a9d7368fc95825c55d225 Mon Sep 17 00:00:00 2001
+From: Jaroslav Rohel <jrohel@redhat.com>
+Date: Tue, 21 Apr 2020 08:56:01 +0200
+Subject: [PATCH 4/4] Append ctx_baseurl prefix to gpg_url (RhBug:1708628)
+
+Sometime the gpg_url contains relative path to context baseurl.
+In that case the code appends baseurl prefix to gpg_url. The resulting
+URI is normalized (solved "//", ".", and "..")
+
+The new function rhsm_url_base_join() introduce similar results
+as utils.url_base_join() in subscription manager.
+---
+ rhsm/rhsm-utils.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 93 insertions(+), 1 deletion(-)
+
+diff --git a/rhsm/rhsm-utils.c b/rhsm/rhsm-utils.c
+index 6708a43a93f850f873a216d6f20aca8b7bd3225e..ee3f296d59c0c4e3c9ed63ccfe460ffdac5bfd3e 100644
+--- a/rhsm/rhsm-utils.c
++++ b/rhsm/rhsm-utils.c
+@@ -179,10 +179,101 @@ rhsm_json_array_is_subset_of_hash_table (JsonArray  *array,
+     }
+ 
+   return TRUE;
+ }
+ 
++/*
++ * Join a baseurl (hostname) and url (full or relpath).
++ *
++ * If url is a full url, just return it. Otherwise combine
++ * it with base, skipping redundant seperators if needed.
++ *
++ * Simulate the behavior of subscription manager.
++ */
++static gchar *
++rhsm_url_base_join (const gchar *base,
++                    const gchar *url)
++{
++  /* handle special cases similar to subscription manager */
++  if (!url || *url == '\0')
++    return g_strdup ("");
++  if (strstr (url, "://"))
++    return g_strdup (url);
++  if (!base || *base == '\0')
++    return g_strdup (url);
++
++  /* parse URI, split to schema, host, and path */
++  g_autofree gchar *schema = NULL;
++  g_autofree gchar *host = NULL;
++  g_autofree gchar *path = NULL;
++  gchar *tmp = strstr (base, ":");
++  if (tmp)
++    schema = g_strndup (base, tmp - base);
++  if (schema)
++    {
++      if (tmp[1] == '/' && tmp[2] == '/')
++      {
++        gchar *tmp2 = strstr (tmp + 3, "/");
++        if (tmp2)
++          {
++            host = g_strndup (tmp + 3, tmp2 - tmp - 3);
++            path = g_strdup (tmp2);
++          }
++        else
++          host = g_strdup (tmp + 3);
++      }
++      else
++        path = g_strdup (tmp + 1);
++    }
++  else
++    path = g_strdup (base);
++
++  /* full_path is path from base + url */
++  g_autofree gchar *full_path = NULL;
++  if (path)
++    full_path = g_strconcat (path, "/", url, NULL);
++  else
++    full_path = g_strconcat ("/", url, NULL);
++
++  /* normalize full_path
++   * split to vector, copy vector but skip empty and "." items,
++   * for each ".." source item remove last item from destination
++   */
++  g_auto(GStrv) src_split_path = g_strsplit (full_path, "/", -1);
++  guint src_len = g_strv_length (src_split_path);
++  g_autofree gchar **dest_split_path = g_new0 (gchar *, src_len + 1);
++  guint dest_len = 0;
++  for (guint src_idx = 0; src_idx < src_len; ++src_idx)
++    {
++      gchar *src = src_split_path[src_idx];
++      if (*src == '\0' || strcmp (src, ".") == 0)
++        continue;
++      if (strcmp (src, "..") == 0)
++        {
++          if (dest_len > 0)
++            --dest_len;
++          continue;
++        }
++      dest_split_path[dest_len++] = src;
++    }
++  dest_split_path[dest_len] = NULL;
++
++  /* construct destination path */
++  g_autofree gchar *tmp_path = g_strjoinv ("/", dest_split_path);
++  g_autofree gchar *dest_path = NULL;
++  if (g_str_has_suffix (url, "/") || g_str_has_suffix (url, "/.") || g_str_has_suffix (url, "/.."))
++    dest_path = g_strconcat (tmp_path, "/", NULL);
++  else
++    dest_path = g_strdup (tmp_path);
++
++  /* construct and return final URI */
++  if (schema)
++    return g_strconcat (schema, "://", host ? host : "", "/", dest_path, NULL);
++  else
++    return g_strconcat ("/", dest_path, NULL);
++}
++
+ /**
+  * rhsm_utils_yum_repo_from_context:
+  * @ctx: an #RHSMContext.
+  *
+  * Returns: (transfer full): a new #GKeyFile.
+@@ -273,11 +364,12 @@ rhsm_utils_yum_repo_from_context (RHSMContext *ctx)
+           g_key_file_set_integer (repofile, id, "enabled", enabled ? 1 : 0);
+ 
+           if (json_object_has_member (repo, "gpg_url"))
+             {
+               const gchar *gpg_url = json_object_get_string_member (repo, "gpg_url");
+-              g_key_file_set_string (repofile, id, "gpgkey", gpg_url);
++              g_autofree gchar *gpgkey = rhsm_url_base_join (ctx_baseurl, gpg_url);
++              g_key_file_set_string (repofile, id, "gpgkey", gpgkey);
+               g_key_file_set_boolean (repofile, id, "gpgcheck", TRUE);
+             }
+           else
+             {
+               /* FIXME: Do we want to enforce gpgcheck? It's unsecure repo. */
+-- 
+2.26.2
+
diff --git a/SPECS/librhsm.spec b/SPECS/librhsm.spec
new file mode 100644
index 0000000..d41eff8
--- /dev/null
+++ b/SPECS/librhsm.spec
@@ -0,0 +1,76 @@
+Name:           librhsm
+Version:        0.0.3
+Release:        7%{?dist}
+Summary:        Red Hat Subscription Manager library
+
+License:        LGPLv2.1+
+URL:            https://github.com/rpm-software-management/librhsm
+Source:         %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
+
+# Patches backported from upstream
+Patch0001:      0001-Replace-bool-option-with-int-to-generate-repo-files.patch
+Patch0002:      0002-Generate-repofile-for-any-architecture-if-ALL-is-spe.patch
+Patch0003:      0003-Enable-repos-when-generating-a-.repo-file-based-on-e.patch
+Patch0004:      0004-Append-ctx_baseurl-prefix-to-gpg_url-RhBug-1708628.patch
+
+BuildRequires:  meson >= 0.37.0
+BuildRequires:  gcc
+BuildRequires:  pkgconfig(glib-2.0) >= 2.44
+BuildRequires:  pkgconfig(gobject-2.0) >= 2.44
+BuildRequires:  pkgconfig(gio-2.0) >= 2.44
+BuildRequires:  pkgconfig(json-glib-1.0) >= 1.2
+BuildRequires:  pkgconfig(openssl)
+
+%description
+%{summary}.
+
+%package devel
+Summary:        Development libraries and header files for %{name}
+Requires:       %{name}%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
+
+%description devel
+%{summary}.
+
+%prep
+%autosetup -p1
+
+%build
+%meson
+%meson_build
+
+%install
+%meson_install
+
+%files
+%license COPYING
+%doc README.md
+%{_libdir}/%{name}.so.*
+
+%files devel
+%{_libdir}/%{name}.so
+%{_includedir}/rhsm/
+%{_libdir}/pkgconfig/%{name}.pc
+
+%changelog
+* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 0.0.3-7
+- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
+  Related: rhbz#1991688
+
+* Wed Jun 16 2021 Mohan Boddu <mboddu@redhat.com> - 0.0.3-6
+- Rebuilt for RHEL 9 BETA for openssl 3.0
+  Related: rhbz#1971065
+
+* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 0.0.3-5
+- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
+
+* Thu Mar 24 2021 Daniel Mach - 0.0.3-4
+- Fix License in spec to LGPLv2.1+ (was LGPLv2+)
+
+* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 0.0.3-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.0.3-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Wed Jul 08 2020 Stephen Gallagher <sgallagh@redhat.com> - 0.0.3-1
+- Initial release