<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Brundha S V</title>
    <description>The latest articles on DEV Community by Brundha S V (@brundhasv).</description>
    <link>https://dev.to/brundhasv</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F226338%2F4a9c1008-d760-4dad-93b2-43c65cb702b1.jpg</url>
      <title>DEV Community: Brundha S V</title>
      <link>https://dev.to/brundhasv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brundhasv"/>
    <language>en</language>
    <item>
      <title>MS Graph API Certificate and Client Secret OAuth2.0 in Java Spring boot</title>
      <dc:creator>Brundha S V</dc:creator>
      <pubDate>Sun, 03 Nov 2024 09:27:53 +0000</pubDate>
      <link>https://dev.to/brundhasv/ms-graph-api-certificate-and-client-credentials-oauth20-in-java-spring-boot-122c</link>
      <guid>https://dev.to/brundhasv/ms-graph-api-certificate-and-client-credentials-oauth20-in-java-spring-boot-122c</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Microsoft Graph API is a gateway to data and service management in Microsoft 365. An access token is required to call MS Graph APIs. In this article we learn how to obtain OAuth access token with a certificate or a secret. This approach is best suited for Admin-Consent Apps that needs access without a user, more info &lt;a href="https://learn.microsoft.com/en-us/graph/auth-v2-service?tabs=http" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Overview
&lt;/h2&gt;

&lt;p&gt;Access Full code here&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/brundhasv" rel="noopener noreferrer"&gt;
        brundhasv
      &lt;/a&gt; / &lt;a href="https://github.com/brundhasv/MSGraphclientCreds" rel="noopener noreferrer"&gt;
        MSGraphclientCreds
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      MS Graph API Certificate and Client credentials OAuth2.0 in Java Spring boot
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;MS Graph API Certificate and Client credentials OAuth2.0 in Java Spring boot&lt;/h1&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Microsoft Graph API is a gateway to data and service management in Microsoft 365. An access token is required to call MS Graph APIs. This repo can be used obtain OAuth access token with a certificate or a secret. This approach is best suited for Admin-Consent Apps that needs access without a user, more info here.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;    String MS_TENANT_ID = "&amp;lt;YOUR_MS_TENANT_ID_HERE&amp;gt;";

    /** 1. Fetch token using certificate */
    AuthResponse response = AuthClient.fetchNewToken(MS_TENANT_ID,"cert");
    log.info("Token Response using Certificate : {}",response);

    /** 2. Fetch token using secret */
    response = AuthClient.fetchNewToken(MS_TENANT_ID,"secret");
    log.info("Token Response using Secret : {}",response);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Explanation of Code here:&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://dev.to/brundhasv/ms-graph-api-certificate-and-client-credentials-authentication-in-java-spring-boot-3hc7" rel="nofollow"&gt;https://dev.to/brundhasv/ms-graph-api-certificate-and-client-credentials-authentication-in-java-spring-boot-3hc7&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/brundhasv/MSGraphclientCreds" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;ul&gt;
&lt;li&gt;Language used - Java Springboot&lt;/li&gt;
&lt;li&gt;Libraries - security library nimbus and bouncycastle &lt;/li&gt;
&lt;li&gt;Project - Maven&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;pom.xml&lt;/u&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;com.nimbusds&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;oauth2-oidc-sdk&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;11.10&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.bouncycastle&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;bcpkix-jdk18on&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.76&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Access token request with a Certificate
&lt;/h2&gt;

&lt;p&gt;OAuth2 Client credentials flow is supported by MS Graph API to obtain access token using certificate. Certificate Auth is recommended over to secret Auth.&lt;br&gt;
&lt;u&gt;Prerequisite&lt;/u&gt;- Your certificate needs to be uploaded under your 'App Registration&amp;gt;Certificates &amp;amp; Secrets'. You can also use self-signed certificate if deployed in local environment.&lt;br&gt;
&lt;u&gt;Reference&lt;/u&gt;- &lt;a href="https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow#second-case-access-token-request-with-a-certificate" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Code Explanation
&lt;/h4&gt;

&lt;p&gt;Use MS token URL and MS App id and uploaded certificate to obtain oauth2 access token.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Populate MS OAuth Token URL, scope and your Entra App id and certificate and its key path in Constants.java. PEM certificate is used in this example. Certificate key is needed to sign JWT Token.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Constants {
    //ms app client/app id
    public static final String MS_APP_CLIENT_ID = "&amp;lt;YOUR_MS_APPLICATION_ID_HERE&amp;gt;";

    //ms graph api oauth token url
    public static final String MS_APP_TOKEN_URL =
            "https://login.microsoftonline.com/%s/oauth2/v2.0/token";

    //ms graph api oauth token url
    public static final String MS_APP_TOKEN_SCOPE = "https://graph.microsoft.com/.default";

    //client certificate details
    public static final String CERT_PATH = "&amp;lt;YOUR_CERT_PATH_HERE&amp;gt;";
    public static final String CERT_KEY_PATH = "&amp;lt;YOUR_CERT_KEY_PATH_HERE&amp;gt;";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Create signed JWT token in the format specified by MS &lt;a href="https://learn.microsoft.com/en-us/entra/identity-platform/certificate-credentials#assertion-format" rel="noopener noreferrer"&gt;assertion-format&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;JWTHeader&lt;/u&gt;&lt;br&gt;
Create JWT header using public key from certificate. PEM type cert is used in this example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X509Certificate cert = getPublicKeyFromCert(Constants.CERT_PATH);
String thumbprint = getThumbprint(cert);
Map&amp;lt;String, Object&amp;gt; jwsMap = new HashMap&amp;lt;&amp;gt;();
jwsMap.put("alg", HEADER_ALG);
jwsMap.put("typ", HEADER_TYP);
jwsMap.put("x5t", thumbprint);
JWSHeader jwsHeader = JWSHeader.parse(jwsMap);
log.debug("JWT header - {}", jwsHeader.toJSONObject());
return jwsHeader;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;u&gt;JWTClaims&lt;/u&gt;&lt;br&gt;
Certificate Claims is built as specified by MS, setting expiration for 10mins and issuer/subject as App client id.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LocalDateTime localDate = LocalDateTime.now();
Date dateNow = Date.from(localDate.atZone(ZoneId.systemDefault()).toInstant());
LocalDateTime localDateExp = localDate.plus(Duration.ofMinutes(JWT_EXPIRY_MINS));
Date dateExp = Date.from(localDateExp.atZone(ZoneId.systemDefault()).toInstant());
UUID uuid = UUID.randomUUID();
JWTClaimsSet jwtClaims =
new JWTClaimsSet.Builder()
        .audience(tokenUrl)
        .issueTime(dateNow)
        .notBeforeTime(dateNow)
        .expirationTime(dateExp)
        .jwtID(uuid.toString())
        .issuer(Constants.MS_APP_CLIENT_ID)
        .subject(Constants.MS_APP_CLIENT_ID)
        .build();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;u&gt;SignedJWT&lt;/u&gt;&lt;br&gt;
Using above created JWT header and Claims, create JWT token and finally sign with certificate private key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; private static SignedJWT createSignedJWT(String tokenUrl) {
    JWSHeader jwsHeader = createJWTHeader();
    JWTClaimsSet jwtClaims = createJWTClaims(tokenUrl);
    SignedJWT signedJWT = new SignedJWT(jwsHeader, jwtClaims);
    RSAPrivateKey certJWK = readPKCS8PrivateKey(Constants.CERT_KEY_PATH);
    try {
        signedJWT.sign(new RSASSASigner(certJWK));
    } catch (Exception e) {
        throw new AuthException("Error while signing JWT", e.toString());
    }
    log.debug("JWT Cert Token for MS App - {}", signedJWT.serialize());
    return signedJWT;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use above created signed JWT to make OAuth request using nimbus library 'PrivateKeyJWT'.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/** Access token request with a certificate */
private static TokenRequest getClientCertTokenRequest(String tenantId)
        throws URISyntaxException {
    String tokenUrl = String.format(Constants.MS_APP_TOKEN_URL, tenantId);
    SignedJWT signedJWT = getSignedJWT(tokenUrl);
    ClientAuthentication clientAuth = new PrivateKeyJWT(signedJWT);
    AuthorizationGrant clientGrant = new ClientCredentialsGrant();
    Scope scope = new Scope(Constants.MS_APP_TOKEN_SCOPE);
    URI tokenEndpoint = new URI(tokenUrl);

    // Make the token request
    return new TokenRequest(tokenEndpoint, clientAuth, clientGrant, scope);
}    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Then with your Org/App Tenant Id, fetch token using above method. Tenant Id is MS account Id for your org/domain, this can be found in your Entra App.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component
@Slf4j
public class AuthCLI implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        String MS_TENANT_ID = "&amp;lt;YOUR_MS_TENANT_ID_HERE&amp;gt;";

        /** 1. Fetch token using certificate */
        AuthResponse response = AuthClient.fetchNewToken(MS_TENANT_ID,"cert");
        log.info("Token Response using Certificate : {}",response);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Access token request with a Secret
&lt;/h2&gt;

&lt;p&gt;OAuth2 Client credentials flow is supported by MS Graph API to obtain access token using secret.&lt;br&gt;
&lt;u&gt;Prerequisite&lt;/u&gt;- You should generate client secret under your 'App Registration&amp;gt;Certificates &amp;amp; Secrets' and note down. This is recommended for test/setup in local environment.&lt;br&gt;
&lt;u&gt;Reference&lt;/u&gt;- &lt;a href="https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow#first-case-access-token-request-with-a-shared-secret" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Code Explanation
&lt;/h4&gt;

&lt;p&gt;Use MS token URL and MS App id and generated secret to obtain oauth2 access token.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Populate MS OAuth Token URL, scope and your Entra App id and generated secret in Constants.java
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Constants {
    //ms app client/app id
    public static final String MS_APP_CLIENT_ID = "&amp;lt;YOUR_MS_APPLICATION_ID_HERE&amp;gt;";

    //client secret
    public static String MS_APP_CLIENT_SECRET = "&amp;lt;YOUR_MS_CLIENT_SECRET_HERE&amp;gt;";

    //ms graph api oauth token url
    public static final String MS_APP_TOKEN_URL =
            "https://login.microsoftonline.com/%s/oauth2/v2.0/token";

    //ms graph api oauth token url
    public static final String MS_APP_TOKEN_SCOPE = "https://graph.microsoft.com/.default";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use nimbus library 'ClientSecretBasic' to make OAuth 2-legged Token request using above parameters.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/** Access token request with a secret */
private static TokenRequest getClientCredsTokenRequest(String tenantId)
        throws URISyntaxException {
    AuthorizationGrant clientGrant = new ClientCredentialsGrant();

    // The credentials to authenticate the client at the token endpoint
    ClientID clientID = new ClientID(Constants.MS_APP_CLIENT_ID);
    Secret clientSecret = new Secret(Constants.MS_APP_CLIENT_SECRET);
    ClientAuthentication clientAuth = new ClientSecretBasic(clientID, clientSecret);

    Scope scope = new Scope(Constants.MS_APP_TOKEN_SCOPE);
    String tokenUrl = String.format(Constants.MS_APP_TOKEN_URL, tenantId);
    URI tokenEndpoint = new URI(tokenUrl);

    // Make the token request
    return new TokenRequest(tokenEndpoint, clientAuth, clientGrant, scope);
}    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Then with your Org/App Tenant Id, fetch token using above method. Tenant Id is MS account Id for your org/domain, this can be found in your Entra App.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component
@Slf4j
public class AuthCLI implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        String MS_TENANT_ID = "&amp;lt;YOUR_MS_TENANT_ID_HERE&amp;gt;";

        /** 2. Fetch token using secret */
        response = AuthClient.fetchNewToken(MS_TENANT_ID,"secret");
        log.info("Token Response using Secret : {}",response);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>springboot</category>
      <category>microsoftgraph</category>
      <category>oauth</category>
      <category>jwt</category>
    </item>
    <item>
      <title>GO Protobuf Encoding/Decoding integrated with C</title>
      <dc:creator>Brundha S V</dc:creator>
      <pubDate>Thu, 24 Oct 2019 10:29:02 +0000</pubDate>
      <link>https://dev.to/brundhasv/go-protobuf-encoding-decoding-integrated-with-c-3ig0</link>
      <guid>https://dev.to/brundhasv/go-protobuf-encoding-decoding-integrated-with-c-3ig0</guid>
      <description>&lt;p&gt;Protobuf messages are gaining popularity across many domains. There are libraries like nanopb in C to support the protobuf encoding/decoding. However they are slow and also pose significant challenge in implementation. GoLang protobuf encoding/decoding is fast and provides support of unmarshalling data from JSON to proto format.&lt;/p&gt;

&lt;p&gt;We will be creating a C shared library containing functions that read from json file, protobuf encode and decode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full Code can be found here:&lt;/strong&gt; &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/brundhasv" rel="noopener noreferrer"&gt;
        brundhasv
      &lt;/a&gt; / &lt;a href="https://github.com/brundhasv/GoC-Protobuf" rel="noopener noreferrer"&gt;
        GoC-Protobuf
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Go functions integrated with C
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;GoC Protobuf Encoding/Decoding&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Go functions for Protobuf Encoding/decoding integrated with C&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Usage:&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;protoc --go_out=. Student.proto&lt;/p&gt;
&lt;p&gt;go build  -o student.so -buildmode=c-shared Student.pb.go student_en_dc.go&lt;/p&gt;
&lt;p&gt;gcc -o student student_cgo.c ./student.so&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Go program can also be run in standalone mode:&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;go run student_en_dc.go Student.pb.go&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Explanation of Code here:&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://dev.to/brundhasv/go-protobuf-encoding-decoding-integrated-with-c-3ig0" rel="nofollow"&gt;https://dev.to/brundhasv/go-protobuf-encoding-decoding-integrated-with-c-3ig0&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/brundhasv/GoC-Protobuf" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h1&gt;
  
  
  GoLang Code
&lt;/h1&gt;

&lt;p&gt;Lets start with &lt;em&gt;Student.proto&lt;/em&gt;. I am using proto3 for this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;syntax="proto3";

package main;

message Parents {
      string dad=1;
      string mom=2;
}

enum Gender {
    Female = 0;
    Male = 1;
}

message Student {
      string name = 1;
      int32 age = 2;
      Parents parents=3;
      Gender gender=4;
}

message Students {
      repeated bytes StudentEntry=1;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As you can see above proto includes enum, nested proto and repeated bytes. &lt;strong&gt;Student&lt;/strong&gt; represents a student's data, each student's data will be encoded and added to &lt;strong&gt;Students&lt;/strong&gt; StudentEntry and all the encoded entries will be encoded again.&lt;/p&gt;

&lt;p&gt;Below is input JSON file &lt;em&gt;student_list.json&lt;/em&gt; which is used to populate proto fields. We have to use the same names and nested levels for the unmarshal of Json to proto.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"0"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Elliot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Age"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Parents"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Dad"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"George"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Mom"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Elena"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Gender"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"David"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Age"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Parents"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Dad"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Keith"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Mom"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sarah"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Gender"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Encoding Protobuf from JSON
&lt;/h2&gt;

&lt;p&gt;To integrate with C, library C is used to convert GoData to C datatypes. Comment &lt;em&gt;export&lt;/em&gt; is used to export functions to C lib. &lt;br&gt;
We will create a new GoLang program file &lt;strong&gt;student_en_dc.go&lt;/strong&gt; and add encode and decode functions to it.&lt;br&gt;
Json file is input parameter of this function &lt;strong&gt;get_student_enbuf&lt;/strong&gt; passed from C. This function returns encoded buffer and its length to C.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//export get_student_enbuf
func get_student_enbuf(student_json_file *C.char) (unsafe.Pointer,C.int) {
       .
       .
       return C.CBytes(students_en),C.int(int32(len(students_en)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;First step in encoding is to Unmarshall JSON to proto. As there are more than one student entries, I have added entries using number keys. This cannot be directly unmarshalled, we would have to extract json data of each student and then unmarshal. I am first unmarshalling json file data to an interface. Below is the code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jsonbytes, _ := ioutil.ReadAll(jsonFile)
var parsed_proto map[string]interface{}
json.Unmarshal(jsonbytes, &amp;amp;parsed_proto)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then parse each interface to obtain student json data and unmarshall it into our proto. Aftermath proto is encoded as shown.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    for i=0;i&amp;lt;len(parsed_proto);i++ {
            selectedjb, err := json.Marshal(parsed_proto[strconv.Itoa(i)])
            if err != nil {
                log.Println("Error in reading json index",err)
                return nil,0
            }
            var parsed_jf map[string]interface{}
            //Each student data to proto
            json.Unmarshal(selectedjb, &amp;amp;parsed_jf)
            student := &amp;amp;Student{}
            //Proto Encoding of student
            json.Unmarshal(selectedjb, student)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Encoded data is added to StudentEntry of Students. Then Students data is encoded. We have the encoded buffer.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            students.StudentEntry=append(students.StudentEntry,student_en)
    }
    students_en, err := proto.Marshal(students)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Decoding protobuf
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Students&lt;/em&gt; is decoded first following all the &lt;em&gt;student&lt;/em&gt; entries.&lt;/p&gt;

&lt;p&gt;Function &lt;strong&gt;decode_student_enbuf&lt;/strong&gt; takes encoded data and its length as input passed from C and returns decoded buffer to C.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//export decode_student_enbuf
func decode_student_enbuf(data *C.char,leng C.int) *C.char {
           .
           .
           return C.CString(decoded_student)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Before decode, *char is converted to GoBytes and then unmarshalled to proto.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new_students := &amp;amp;Students{}
student_en:=C.GoBytes(unsafe.Pointer(data),leng)
err := proto.Unmarshal(student_en, new_students)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Decoded &lt;em&gt;students&lt;/em&gt; data is used to obtain each &lt;em&gt;StudentEntry&lt;/em&gt; and is decoded. Decoded student is appended to a string and is returned to C.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for i=0;i&amp;lt;len(new_students.StudentEntry);i++ {
        new_student := &amp;amp;Student{}
        err = proto.Unmarshal(new_students.StudentEntry[i], new_student)
        decoded_student=decoded_student+"\n"+proto.MarshalTextString(new_student)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h1&gt;
  
  
  Building C-Shared file
&lt;/h1&gt;

&lt;p&gt;Lets compile proto to generate &lt;em&gt;Student.pb.go&lt;/em&gt;.Then build c-shared file.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protoc --go_out=. Student.proto
go build  -o student.so -buildmode=c-shared Student.pb.go student_en_dc.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;student.so&lt;/em&gt; and &lt;em&gt;student.h&lt;/em&gt; files are generated. &lt;br&gt;
Following lines would be present in the generated header file. Golang function &lt;em&gt;get_student_enbuf&lt;/em&gt; returns tuple(more than one return parameters), this is converted to struct when header files are generated as seen below.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Return type for get_student_enbuf */
struct get_student_enbuf_return {
        void* r0;
        int r1;
};

extern struct get_student_enbuf_return get_student_enbuf(char* p0);

extern char* decode_student_enbuf(char* p0, int p1);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h1&gt;
  
  
  C Code
&lt;/h1&gt;

&lt;p&gt;From C side, generated header file is included. Students list JSON file is passed  to function &lt;em&gt;get_student_enbuf&lt;/em&gt;, returned encoded buffer and its length is populated in struct stu. The same are passed to decode function &lt;em&gt;decode_student_enbuf&lt;/em&gt;, the returned decoded string is printed.&lt;br&gt;
Finally both encoded and decoded buffers are freed.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include "student.h"
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;stdbool.h&amp;gt;

struct get_student_enbuf_return stu;

int main() {
    stu = get_student_enbuf("student_list.json");
    int stu_list_len = stu.r1;
    if(stu.r0!=NULL) {
        char *decoded_stu = decode_student_enbuf((char*)stu.r0,stu.r1);
        if(decoded_stu != NULL){
                printf("%s",decoded_stu);
                free((char*)decoded_stu);
        }
    free((char*)stu.r0);
    }
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Compiling and executing C
&lt;/h2&gt;

&lt;p&gt;Link with the created &lt;em&gt;student.so&lt;/em&gt;, create object &lt;em&gt;student&lt;/em&gt; and run the object.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gcc -o student student_cgo.c ./student.so

./student
name: "Elliot"
age: 15
parents: &amp;lt;
  dad: "George"
  mom: "Elena"
&amp;gt;

name: "David"
age: 14
parents: &amp;lt;
  dad: "Keith"
  mom: "Sarah"
&amp;gt;
gender: Male

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Full Code can be found here:&lt;/strong&gt; &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/brundhasv" rel="noopener noreferrer"&gt;
        brundhasv
      &lt;/a&gt; / &lt;a href="https://github.com/brundhasv/GoC-Protobuf" rel="noopener noreferrer"&gt;
        GoC-Protobuf
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Go functions integrated with C
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;GoC Protobuf Encoding/Decoding&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;Go functions for Protobuf Encoding/decoding integrated with C&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Usage:&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;protoc --go_out=. Student.proto&lt;/p&gt;

&lt;p&gt;go build  -o student.so -buildmode=c-shared Student.pb.go student_en_dc.go&lt;/p&gt;

&lt;p&gt;gcc -o student student_cgo.c ./student.so&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Go program can also be run in standalone mode:&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;go run student_en_dc.go Student.pb.go&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Explanation of Code here:&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://dev.to/brundhasv/go-protobuf-encoding-decoding-integrated-with-c-3ig0" rel="nofollow"&gt;https://dev.to/brundhasv/go-protobuf-encoding-decoding-integrated-with-c-3ig0&lt;/a&gt;&lt;/p&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/brundhasv/GoC-Protobuf" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>go</category>
      <category>c</category>
      <category>json</category>
      <category>proto</category>
    </item>
  </channel>
</rss>
