apiautomationsmime

pushing SMIME cert to users in Google work space using Google API python


I am in a desperate need to push SMIME certs to more than 300 users in Googleworkspace.

I have tried to follow the API documentation but I am not sure what I am doing wrong, I have a deception error and when I ignore it I get 400 response that the json file is not correct. I am using a delegated service account to be able to impersonate the users. I can list lables within thier inbox but i cannot upload the certificate to ther sittings. I am using the right scope not labels.

from __future__ import print_function

def main():
    creds = None

    SCOPES = ['https://www.googleapis.com/auth/gmail.labels']
    SERVICE_ACCOUNT_FILE = 'D:\G_Mail_Certs\eproject-444444444f.json'

    credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    try:
        delegated_credentials = credentials.with_subject('targetuser@domain.com')       
        gmail_service = build('gmail', 'v1', credentials=delegated_credentials)
        user_id = 'targetuser@domain.com'
        smime_info = create_smime_info(cert_filename='D:\Certs\MPS2.pfx', cert_password='ABCD1234')
        results = gmail_service.users().settings().sendAs().smimeInfo().\
            insert(userId=user_id, sendAsEmail=send_as_email, body=smime_info)\
            .execute() 

    except HttpError as error:
        print(f'An error occurred: {error}')

    return results

if __name__ == '__main__':
    main()

the functionalities.py is

def create_smime_info(cert_filename, cert_password=None):
    """Create an smimeInfo resource for a certificate from file.
    Args:
      cert_filename: Name of the file containing the S/MIME certificate.
      cert_password: Password for the certificate file, or None if the file is not
          password-protected.
    """
    smime_info = None
    try:
        with open(cert_filename, 'r') as f:
            smime_info = {}
            data = f.read().encode('UTF-8')
            smime_info['pkcs12'] = base64.urlsafe_b64encode(data)
            if cert_password and len(cert_password) > 0:
                smime_info['encryptedKeyPassword'] = cert_password
    except (OSError, IOError) as error:
        print('An error occurred while reading the certificate file: %s' % error)

    return smime_info


# [END create_smime_info]


# [START insert_smime_info]
def insert_smime_info(service, user_id, smime_info, send_as_email=None):
    """Upload an S/MIME certificate for the user.
    Args:
      service: Authorized GMail API service instance.
      user_id: User's email address.
      smime_info: The smimeInfo resource containing the user's S/MIME certificate.
      send_as_email: The "send as" email address, or None if it should be the same
          as user_id.
    """
    if not send_as_email:
        send_as_email = user_id
    try:
        results = service.users().settings().sendAs().smimeInfo().insert(
            userId=user_id, sendAsEmail=send_as_email, body=smime_info).execute()
        print('Inserted certificate; id: %s' % results['id'])
        return results
    except errors.HttpError as error:
        print('An error occurred: %s' % error)
        return None


# [END insert_smime_info]

thank you


Solution

  • Just in case if anyone needed it, here is what I have done.. I changed the create_smime_info function to run without encoding.

    def create_smime_info(cert_filename, cert_password):
    """Create an smimeInfo resource for a certificate from file.
    Args:
      cert_filename: Name of the file containing the S/MIME certificate.
      cert_password: Password for the certificate file, or None if the file is not
          password-protected.
    Returns : Smime object, including smime information
    """
    
    smime_info = None
    try:
        with open(cert_filename, 'rb') as cert:
            smime_info = {}
            data = cert.read()
            smime_info['pkcs12'] = base64.urlsafe_b64encode(data).decode()
            if cert_password and len(cert_password) > 0:
                smime_info['encryptedKeyPassword'] = cert_password
    
    except (OSError, IOError) as error:
        print(F'An error occurred while reading the certificate file: {error}')
        smime_info = None
    
    return smime_info
    

    Worked fine with me and I was able to attach certs to all domain accounts.